Phalcon Framework 1.3.4

PDOException: SQLSTATE[HY000]: General error: 2006 MySQL server has gone away

/home/ec2-user/www2/dailymore/app/controllers/SiteControllerBase.php (892)
#0PDOStatement->execute()
#1Phalcon\Db\Adapter\Pdo->executePrepared(Object(PDOStatement), Array([content_type] => 6, [now] => 2018-11-14 22:48:44, [base_content_id] => 32542, [deleted] => 0, [status] => 100), null)
#2Phalcon\Db\Adapter\Pdo->query(SELECT `contents`.`id`, `contents`.`users_id`, `contents`.`categories_id`, `contents`.`preview_key`, `contents`.`pages`, `contents`.`type`, `contents`.`url`, `contents`.`permalink`, `contents`.`title`, `contents`.`tags`, `contents`.`sub_title`, `contents`.`image`, `contents`.`image_thumbnail`, `contents`.`image_rectangle`, `contents`.`lead`, `contents`.`head_credit`, `contents`.`foot_credit`, `contents`.`author`, `contents`.`layout`, `contents`.`template`, `contents`.`mark`, `contents`.`hot_tips`, `contents`.`top_waku_show_flag`, `contents`.`display_option`, `contents`.`book_number`, `contents`.`book_date`, `contents`.`book_price`, `contents`.`book_html`, `contents`.`present_expiration_date`, `contents`.`release_date`, `contents`.`expiration_date`, `contents`.`created_at`, `contents`.`updated_at`, `contents`.`created_user`, `contents`.`updated_user`, `contents`.`deleted`, `contents`.`memo`, `contents`.`status`, `contents`.`monitoring`, `contents`.`pageview`, `contents`.`weekly_pageview`, `contents`.`monthly_pageview`, `contents`.`ad_flag`, `contents`.`manage_type` FROM `contents` WHERE ((((`contents`.`status` = :status) AND (`contents`.`deleted` = :deleted)) AND (`contents`.`id` <> :base_content_id)) AND (:now BETWEEN `contents`.`release_date` AND `contents`.`expiration_date`)) AND (`contents`.`type` = :content_type) ORDER BY `contents`.`release_date` DESC, `contents`.`id` ASC LIMIT 1 OFFSET 0, Array([content_type] => 6, [now] => 2018-11-14 22:48:44, [base_content_id] => 32542, [deleted] => 0, [status] => 100), null)
#3Phalcon\Mvc\Model\Query->_executeSelect(Array([models] => Array([0] => Contents), [tables] => Array([0] => contents), [columns] => Array([contents] => Array([type] => object, [model] => Contents, [column] => contents, [balias] => contents)), [where] => Array([type] => binary-op, [op] => AND, [left] => Array([type] => parentheses, [left] => Array()), [right] => Array([type] => parentheses, [left] => Array())), [order] => Array([0] => Array([0] => Array(), [1] => DESC), [1] => Array([0] => Array(), [1] => ASC)), [limit] => Array([number] => Array([type] => literal, [value] => 1), [offset] => Array([type] => literal, [value] => 0))), Array([content_type] => 6, [now] => 2018-11-14 22:48:44, [base_content_id] => 32542, [deleted] => 0, [status] => 100), null)
#4Phalcon\Mvc\Model\Query->execute()
<?php
 
use Phalcon\Mvc\View;
use Phalcon\Tag;
 
class SiteControllerBase extends ControllerBase
{
    const DEVICE_PC = 1;
    const DEVICE_SP = 2;
    const POPIN_VIEW_SCROLL_NUM = 4;
    const LOGLY_VIEW_SCROLL_NUM = 6;
    const SHOPPING_VIEW_SCROLL_NUM = 8;
 
    public $device;
    public $categories_cache;
    public $current_url;
    public $og = array();
    public $meta = array();
    public $breadcrumb = array();
 
    /** admin user check **/
    protected function initialize()
    {
 
        Tag::prependTitle('DAILY MORE');
 
        $this->meta['keywords'] = $this->meta_settings->keywords_list->default;
        $this->meta['description'] = $this->meta_settings->description_list->default;
        $this->view->meta = $this->meta;
 
        // デバイス判定
        $this->device_check();
 
        // 現在アクセス中のフルパスURL
        $this->view->current_url = $this->current_url = "https://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";
 
        // PCとスマホの振り分け
        if ( $this->device == self::DEVICE_SP ) {
            $this->sp_setup();
        } else {
            $this->pc_setup();
        }
 
        // 格納画像のURL
        $this->view->image_url = $this->config->application->imageUrl;
 
        // カテゴリー情報キャッシュの組み込み
        $this->categories_cache();
 
        //パンくずリストの初期設定
        $this->setDefaultBreadcrumb();
 
        // サイドのモアハピ部新着
        $this->sideMorehapiContents();
 
        // サイドのランキングを取得
        $this->side_rankings();
 
        //サイドのMORE MODELS
        $this->side_moremodels();
 
        // サイドのキーワード
        $this->side_link_keywords();
 
        // サイドの試し読み
        $this->sideMagazineContents();
 
        //サイドの動画誘導枠
        $this->sideMovieLinks();
 
        // サイドのFEATURE
        $this->sideFeatureContents();
 
        // サイドのInlinebanner
        $this->sideInlinebannerLinks();
 
        // OGP 各コントローラーで上書きする。
        $this->og['title'] = $this->meta_settings->title_list->default;
        $this->og['description'] = $this->meta_settings->description_list->default;
        $this->og['image'] = 'https://more.hpplus.jp/site/img/ogp.jpg';
        $this->og['url'] = $this->current_url;
        $this->og['type'] = 'website';
        $this->og['site_name'] = $this->meta_settings->title_list->default;
 
        $this->view->og = $this->og;
 
        // 新着リボンをつける基準時間
        $this->view->new_datetime = date('Y-m-d H:i:s', strtotime("-1 day"));
 
        // SPのページでviewport の user scale no を外す場合は true
        $this->view->viewport_user_scalable = false;
 
        $this->view->ad_category = 'cattop';
 
        $this->view->newslink_categories = (array)$this->newslink_settings->event_category;
 
    }
 
    /**
     * 動画誘導枠5件をviewに渡す(優先順位順)
     */
    private function sideMovieLinks()
    {
        $links = $this->modelsManager->createBuilder();
        $links->from('Links')
            ->where('deleted = :deleted:', array('deleted' => ModelBase::ACTIVE_PARAM))
            ->andWhere('status = :status:', array('status' => Links::LINKS_STATUS_RELESE))
            ->andWhere('type = :type:', array('type' => Links::LINKS_TYPE_MOVIE))
            ->andWhere(':now: BETWEEN release_date AND expiration_date', array('now' => date('Y-m-d H:i:s')))
            ->orderBy('CAST(name AS SIGNED), release_date DESC')
            ->limit(5);
        $this->view->movie_links = $links->getQuery()->execute();
    }
 
    /**
     * Flagshop誘導枠をDBから取得して返す
     * @return mixed
     */
    public function getShoppingLinks()
    {
        $links = $this->modelsManager->createBuilder();
        $links->from('Links')
            ->where('deleted = :deleted:', array('deleted' => ModelBase::ACTIVE_PARAM))
            ->andWhere('status = :status:', array('status' => Links::LINKS_STATUS_RELESE))
            ->andWhere('type = :type:', array('type' => Links::LINKS_TYPE_SHOPPING))
            ->andWhere(':now: BETWEEN release_date AND expiration_date', array('now' => date('Y-m-d H:i:s')))
            ->orderBy('CAST(name AS SIGNED), release_date DESC');
        $result = $links->getQuery()->execute();
        if ( $result->count() == 0 ) {
            return;
        }
        return $result;
    }
 
    /**
     * インラインバナーの設定情報をviewに渡す
     */
    private function sideInlinebannerLinks()
    {
        $links = $this->modelsManager->createBuilder();
        $links->from('Links')
            ->where('deleted = :deleted:', array('deleted' => ModelBase::ACTIVE_PARAM))
            ->andWhere('status = :status:', array('status' => Links::LINKS_STATUS_RELESE))
            ->andWhere('type = :type:', array('type' => Links::LINKS_TYPE_INLINE_BANNER))
            ->andWhere(':now: BETWEEN release_date AND expiration_date', array('now' => date('Y-m-d H:i:s')))
            ->orderBy('name, release_date DESC');
        $result = $links->getQuery()->execute();
        $inline_banners = array();
        if ( $result->count() > 0 ) {
            foreach ( $result as $banner ) {
                if ( !isset($inline_banners[$banner->name]) ) {
                    $inline_banners[$banner->name] = $banner;
                }
            }
        }
        $this->view->inlinebanner_links = $inline_banners;
    }
 
    /**
     * パンくずリストの初期設定
     */
    private function setDefaultBreadcrumb()
    {
        $arr_path = explode('/', $this->router->getRewriteUri());
 
        $this->breadcrumb['top'] = array('name' => 'TOP', 'uri' => '');
        if ( !empty($arr_path[1]) ) {
            $this->breadcrumb['cat_top'] = array('name' => $this->categories_cache['url'][$arr_path[1]]['name'], 'uri' => $arr_path[1]);
        }
 
        if ( !empty($arr_path[2]) ) {
            $this->breadcrumb['sub_cat_top'] = array('name' => $this->categories_cache['url'][$arr_path[2]]['name'], 'uri' => $arr_path[1] . '/' . $arr_path['2']);
        }
 
        $this->view->breadcrumb = $this->breadcrumb;
    }
 
    /**
     * スマホの設定を反映
     */
    public function sp_setup()
    {
        // スマホのテンプレート場所
        $this->view->setViewsDir($this->config->application->sp_viewDir);
        $this->view->setLayoutsDir('layouts/');
        $this->view->setPartialsDir('partials/');
        $this->view->setLayout("default");
        $this->view->setMainView('main');
 
    }
 
    /**
     * PCの設定を反映
     */
    public function pc_setup()
    {
 
        // PCのテンプレート場所
        $this->view->setViewsDir($this->config->application->pc_viewDir);
        $this->view->setLayoutsDir('layouts/');
        $this->view->setPartialsDir('partials/');
        $this->view->setLayout("default");
        $this->view->setMainView('main');
 
    }
 
    /**
     * Index action
     */
    public function indexAction()
    {
 
    }
 
    /**
     * モアハピ部最新記事を取得(投稿ユーザーはユニークにする)
     */
    //TODO:処理の見直し(何故40件か)
    public function sideMorehapiContents()
    {
        $limit = 40;
        $morehapi_contents = $this->fetch_morehapi_new_contents($limit);
        $this->view->morehapi_contents = $morehapi_contents->filter(function ($r) use (&$ids) {
            if ( !array_key_exists($r->users_id, $ids) ) {
                $ids[$r->users_id] = 1;
                return $r;
            }
        });
    }
 
    protected function fetch_morehapi_new_contents($limit = null, $category_id = null, $user_id = null)
    {
 
        $phql = "
            SELECT
                Contents.id,
                Contents.categories_id,
                Contents.users_id,
                Contents.mark,
                Contents.title,
                Contents.release_date,
                Contents.image,
                Contents.image_rectangle,
                Contents.image_thumbnail,
                Contents.type,
                Users.blog_url as users_blog_url,
                Users.blog_url_image as users_blog_url_image,
                Users.blog_title as users_blog_title,
                Users.name as users_name
            FROM
                Contents, Users
            WHERE
                Contents.users_id = Users.id AND
                Contents.status = :status: AND
                Contents.type = :type: AND
                :now: BETWEEN Contents.release_date AND Contents.expiration_date AND
                Contents.deleted = :deleted:
        ";
 
        $cache_file_name = __FUNCTION__;
        if ( is_array($category_id) ) {
            $phql .= " AND Contents.categories_id IN (" . implode(',', $category_id) . ")";
            $cache_file_name .= '_categories';
        } elseif ( !empty($category_id) ) {
            $phql .= " AND Contents.categories_id = " . $category_id;
            $cache_file_name .= '_category';
        }
 
        if ( !empty($user_id) ) {
            $phql .= " AND Contents.users_id = " . $user_id;
            $cache_file_name .= '_user';
        }
 
        $phql .= " ORDER BY
            release_date DESC
            ";
 
        if ( !empty($limit) ) {
            $phql .= " LIMIT " . $limit;
        }
        $query = $this->modelsManager->createQuery($phql);
 
        $query->cache(
            [
                'key' => $this->create_cache_key($cache_file_name, [$category_id, $user_id, $limit]),
                'lifetime' => $this->config->models->cacheLifetime10min
            ]
        );
 
        $contents = $query->execute(
            [
                "status" => Contents::CONTENTS_STATUS_RELESE,
                "type" => Contents::CONTENTS_TYPE_MOREHAPI,
                "now" => date('Y-m-d H:i:s'),
                "deleted" => ModelBase::NOT_DELETED
            ]
        );
        return $contents;
    }
 
    /**
     * サイドの記事ランキングを共通に呼び出す
     */
    public function side_rankings()
    {
        if ( $this->breadcrumb['cat_top']['uri'] !== 'ranking' ) {
            $limit = 9;
            $this->view->category_rankings = $this->fetch_weekly_article_ranking_parts($limit);
        }
    }
 
    public function fetch_weekly_article_ranking_parts($limit)
    {
        $category_rankings['all'] = $this->fetch_weekly_article_ranking($limit);
        $ranking_categories = array('fashion', 'beauty', 'love', 'odekake');
 
        foreach ( $ranking_categories as $category ) {
            $categories_id = $this->categories_cache['url'][$category]['id'];
            if ( empty($categories_id) ) {
                $category_rankings[$category] = null;
                continue;
            }
 
            $border = '-1 week';
            if ( $category == 'love' ) {
                $border = '-3 month';
            }
 
            $sub_categories = $this->categories_cache['parent_categories_id'][$categories_id];
            $categories_id_list = array_column($sub_categories, 'id');
            $categories_id_list[] = $categories_id;
 
            $category_rankings[$category] = $this->fetch_weekly_article_ranking($limit, $categories_id_list, null, $border);
        }
        return $category_rankings;
    }
 
    public function side_link_keywords()
    {
        $keywords = Links::find(
            [
                "conditions" => "
                type = :type: and
                status = :status: and
                :now: between release_date and expiration_date
            ",
                "bind" => [
                    "status" => Links::LINKS_STATUS_RELESE,
                    "type" => Links::LINKS_TYPE_KEYWORD,
                    "now" => date('Y-m-d H:i:s')],
                "order" => "name * 1",
                "cache" =>
                    [
                        "key" => $this->create_cache_key(__FUNCTION__),
                        "lifetime" => $this->config->models->cacheLifetime1H
                    ]
            ]
        );
 
        if ( $keywords->count() !== 0 ) {
            $this->view->link_keywords = $keywords;
        }
 
    }
 
    /**
     * 記事ランキング
     * 直近1週間以内に公開された記事を対象に
     * PV数が多い記事情報をDBから取得して返す
     *
     * @param int $limit
     * @param array|null $categories_list
     * @param array|null $remove_categories_list
     * @param string $border
     * @return object 記事情報
     */
    public function fetch_weekly_article_ranking($limit = null, $categories_list = null, $remove_categories_list = null, $border = '-1 week')
    {
        $phql = "
            SELECT
                Contents.id,
                Contents.categories_id,
                Contents.users_id,
                Contents.title,
                Contents.mark,
                Contents.release_date,
                Contents.image,
                Contents.image_rectangle,
                Contents.image_thumbnail,
                Contents.type,
                Users.blog_title as blog_title
            FROM
                Contents, Users
            WHERE
                Contents.users_id = Users.id and
                Contents.status = :status: AND
                Contents.type IN (:type_news:, :type_page:, :type_blog:) AND
                :now: BETWEEN Contents.release_date AND Contents.expiration_date AND
                Contents.release_date > :border: AND
                Contents.deleted = :deleted: AND
                Contents.weekly_pageview <> 0 AND
                Contents.categories_id != :present:
            ";
 
 
        $remove_categories = $this->removePhotoCategories();
        if ( $remove_categories ) {
            $phql .= " AND Contents.categories_id NOT IN (" . implode(',', $remove_categories) . ")";
        }
 
        $cache_file_name = __FUNCTION__;
        if ( !empty($categories_list) ) {
            $phql .= " AND Contents.categories_id IN (" . implode(',', $categories_list) . ")";
            $cache_file_name .= '_categories';
        }
 
        if ( !empty($remove_categories_list) ) {
            $phql .= " AND Contents.categories_id NOT IN (" . implode(',', $remove_categories_list) . ")";
            $cache_file_name .= '_remove_categories';
        }
 
        $phql .= " ORDER BY Contents.weekly_pageview DESC";
 
        if ( !empty($limit) ) {
            $phql .= " LIMIT " . $limit;
        }
 
        $query = $this->modelsManager->createQuery($phql);
 
        $query->cache(
            [
                "key" => $this->create_cache_key($cache_file_name, [$categories_list, $limit]),
                "lifetime" => $this->config->models->cacheLifetime3H
            ]
        );
 
        $contents = $query->execute(
            [
                "status" => Contents::CONTENTS_STATUS_RELESE,
                "type_news" => Contents::CONTENTS_TYPE_NEWS,
                "type_page" => Contents::CONTENTS_TYPE_PAGE,
                "type_blog" => Contents::CONTENTS_TYPE_BLOG,
                "now" => date("Y-m-d H:i:s"),
                "border" => date("Y-m-d H:i:s", strtotime($border)),
                "deleted" => ModelBase::NOT_DELETED,
                "present" => Contents::CONTENTS_PRESENTS_CATEGORY
            ]
        );
 
        return $contents;
    }
 
    private function removePhotoCategories()
    {
        //除外するphotoカテゴリーに紐づくサブカテのIDリストを取得
        $photo_parent_id = $this->categories_cache['url']['photo']['id'];
        if ( !$photo_parent_id ) {
            return null;
        }
 
        $photo_categories = array($photo_parent_id);
        if ( !$this->categories_cache['parent_categories_id'][$photo_parent_id] ) {
            return $photo_categories;
        };
 
        foreach ( $this->categories_cache['parent_categories_id'][$photo_parent_id] as $photo_sub_category ) {
            $photo_categories[] = $photo_sub_category['id'];
        }
        return $photo_categories;
    }
 
    public function side_moremodels()
    {
        // モアモデルズの大カテゴリidからサブかて(モデルのデジレポカテゴリ)リストを取得
        $current_parent_categories_id = $this->categories_cache['url']['more-models']['id'];
        $current_subcategories = $this->categories_cache['parent_categories_id'][$current_parent_categories_id];
 
        $subcatList = array();
        $links = array(); // サブカテゴリurlから -digirepo 文字列を省いたものがmodel のURL
        foreach ( $current_subcategories as $cat ) {
            array_push($subcatList, $cat['id']);
            $links[$cat['id']] = preg_replace('/\-digirepo/', '', $this->categories_cache['id'][$cat['id']]['url']);
        }
        $this->view->model_url_from_id = $links;
 
        $moremodels_contents = Contents::find(
            array(
                "conditions" =>
                    "categories_id in (" . implode(',', $subcatList) . ") and
                status = :status: and
                type = :type: and
                :now: between release_date and expiration_date
                ",
                "bind" => array(
                    "status" => Contents::CONTENTS_STATUS_RELESE,
                    "type" => Contents::CONTENTS_TYPE_NEWS,
                    "now" => date('Y-m-d H:i:s'),
                ),
                "order" => "release_date DESC, created_at DESC, updated_at DESC",
                "limit" => 6,
            ));
 
        $categories = Categories::find(
            array(
                "conditions" =>
                    "parent_categories_id = :parent_categories_id:",
                "bind" => [
                    'parent_categories_id' => $this->categories_cache['url']['more-models']['id'],
                ]
            ));
 
        $models_image_list = array();
        foreach ( $categories as $category ) {
            $models_image_list[$category->id] = $category->image_thumbnail;
        }
        $this->view->models_image_list = $models_image_list;
 
        if ( count($moremodels_contents) ) {
            $this->view->moremodels_contents = $moremodels_contents;
            $this->view->moremodels_content_top = $moremodels_contents->getFirst();
        }
    }
 
    public function device_check()
    {
        $ua = $this->request->getUserAgent();
        if (
            //判別条件start
            (strpos($ua, 'iPhone') !== false) //iphoneか、
            || ((strpos($ua, 'Android') !== false) && (strpos($ua, 'Mobile') !== false)) //またはAndroidMobile端末、
            || (strpos($ua, 'Windows Phone') !== false) //またはWindowsPhone、
            || (strpos($ua, 'BlackBerry') !== false) //またはBlackBerryの場合
            //判別条件end
        ) {
 
            $this->device = self::DEVICE_SP;
 
        } else {
            $this->device = self::DEVICE_PC;
 
        }
    }
 
    // カテゴリテーブル情報をカテゴリURLをキーに取得する(キャッシュする)
    public function categories_cache()
    {
        $categories = Categories::find(array(
            "conditions" => "id is not null",
            "order" => "sort",
        ));
 
        $dict = array();
        $dummy = $categories->filter(function ($r) use (&$dict) {
            $dict['id'][$r->id] =
            $dict['parent_categories_id'][$r->parent_categories_id][] =
            $dict['url'][$r->url] = array(
                'id' => $r->id,
                'url' => $r->url,
                'name' => $r->name,
                'parent_categories_id' => $r->parent_categories_id,
                'status' => $r->status,
                'sort' => $r->sort,
            );
 
        });
 
        $this->view->categories_cache = $dict;
        $this->categories_cache = $dict;
 
    }
 
    // 404エラーを出力する
    public function return404()
    {
        $this->dispatcher->forward(array('controller' => 'error', 'action' => 'show404'));
        return false;
    }
 
    public function search_result_contents($keyword)
    {
        $phql = "
            SELECT
                Contents.id,
                Contents.categories_id,
                Contents.users_id,
                Contents.title,
                Contents.mark,
                Contents.release_date,
                Contents.lead,
                Contents.image,
                Contents.image_rectangle,
                Contents.image_thumbnail,
                Contents.type,
                ContentBlocks.title as block_title,
                ContentBlocks.body,
                Users.blog_title,
                Users.blog_url
            FROM Contents
            LEFT JOIN ContentBlocks ON Contents.id = ContentBlocks.contents_id
            LEFT JOIN Users ON Contents.users_id = Users.id
            LEFT JOIN ContentPoints ON Contents.id = ContentPoints.content_id
            WHERE
                Contents.status = :status: and
                Contents.type != :type_book: and
                Contents.deleted = :deleted: and
                :now: between Contents.release_date and Contents.expiration_date and
                (
                    Contents.title like :keyword: or
                    ContentBlocks.title like :keyword: or
                    ContentBlocks.body like :keyword: or
                    ContentPoints.body like :keyword:
                )
            GROUP BY Contents.id
            ORDER BY Contents.release_date DESC, Contents.created_at DESC, Contents.updated_at DESC
            ";
 
        $contentsQuery = $this->modelsManager->createQuery($phql);
        $contentsQuery->cache([
            "key" => 'site_keyword_' . md5($keyword),
            "lifetime" => $this->config->models->cacheLifetime30min
        ]);
 
        $contents = $contentsQuery->execute(
            [
                'status' => Contents::CONTENTS_STATUS_RELESE,
                'type_book' => Contents::CONTENTS_TYPE_BOOK,
                'deleted' => ModelBase::NOT_DELETED,
                "now" => date('Y-m-d H:i:s'),
                "keyword" => "%" . $keyword . "%"
            ]);
        return $contents;
    }
 
    /**
     * 同カテゴリの前後の記事を取得(公開日順)
     * @param $category_id
     * @param $contents_type
     * @param $release_date
     */
    public function getAroundContents($category_id, $contents_type, $release_date)
    {
        $around_contents = array();
        $around_contents['next'] = Contents::findFirst([
            "conditions" =>
                "categories_id = :categories_id: and
                status = :status: and
                type = :type: and
                :now: between release_date and expiration_date and
                release_date > :border: and
                mark = :mark:
            ",
            "bind" => [
                "categories_id" => $category_id,
                "status" => Contents::CONTENTS_STATUS_RELESE,
                "type" => $contents_type,
                "now" => date('Y-m-d H:i:s'),
                "border" => date('Y-m-d H:i:s', strtotime($release_date)),
                "mark" => Contents::CONTENTS_MARK_NORMAL
            ],
            "order" => "release_date"
        ]);
 
        $around_contents['prev'] = Contents::findFirst([
            "conditions" =>
                "categories_id = :categories_id: and
                status = :status: and
                type = :type: and
                :now: between release_date and expiration_date and
                release_date < :border: and
                mark = :mark:
            ",
            "bind" => [
                "categories_id" => $category_id,
                "status" => Contents::CONTENTS_STATUS_RELESE,
                "type" => $contents_type,
                "now" => date('Y-m-d H:i:s'),
                "border" => date('Y-m-d H:i:s', strtotime($release_date)),
                "mark" => Contents::CONTENTS_MARK_NORMAL
            ],
            "order" => "release_date DESC"
        ]);
        return $around_contents;
    }
 
    public function create_cache_key($function = 'non_function_name', $param = null)
    {
        $key = '';
        if ( is_array($param) ) {
            foreach ( $param as $val ) {
                if ( is_array($val) ) {
                    $key .= self::create_cache_key(false, $val) . '_';
                } else {
                    $key .= '_' . $val;
                }
            }
        } else {
            $key .= $param;
        }
 
        if ( $function !== false ) {
            $key = $function . '_' . md5($key);
        }
        return $key;
    }
 
    /**
     * ご当地モアの記事下誘導枠設定をDBから取得して返す
     * @return mixed
     */
    public function getAreaLinks()
    {
        $links = Links::find(array(
            "conditions" =>
                "status = :status: and 
                 type = :type: and 
                 :now: between release_date and expiration_date
                 ",
            "bind" => array(
                "status" => Links::LINKS_STATUS_RELESE,
                "type" => Links::LINKS_TYPE_AREA,
                "now" => date('Y-m-d H:i:s'),
            ),
            "order" => "CAST(name AS SIGNED), release_date DESC",
            "limit" => 8
        ));
 
        if ( $links->count() > 0 ) {
            return $links;
        }
        return;
    }
 
    /**
     * meta情報の設定
     *
     * @param string $category
     * @param string $middle_title
     * @param array $option
     * @param integer $page
     *
     * @return void viewに値を渡す
     */
    public function setMetaTag($category, $middle_title = 'default', $option = array(), $page = 1)
    {
        $meta = $this->meta_settings;
 
        $meta_title = $meta->title_list->{$category};
        if ( isset($option['title']) ) {
            $meta_title = $option['title'];
        }
 
        $meta_title = $this->addPageNum($meta_title, $page);
        $this->tag->prependTitle($meta_title . ' | ' . $meta->middle_title->{$middle_title});
 
        $this->meta['description'] = $meta->description_list->default;
        if ( !empty($meta->description_list->{$category}) ) {
            $this->meta['description'] = $meta->description_list->{$category};
        }
 
        $this->meta['keywords'] = $meta->keywords_list->default;
        if ( !empty($meta->keywords_list->{$category}) ) {
            $this->meta['keywords'] = $meta->keywords_list->{$category};
        }
 
        $this->og['title'] = $meta_title;
        $this->og['description'] = $this->meta['description'];
 
        if ( !empty($option) ) {
            foreach ( $option as $key => $val ) {
                if ( $key === 'description' || $key === 'keywords' ) {
                    $this->meta[$key] = $val;
                }
                $this->og[$key] = $val;
            }
        }
 
        $this->view->og = $this->og;
        $this->view->meta = $this->meta;
    }
 
    /**
     * description用に指定された長さにテキストを丸める
     *
     * @param string $description
     * @param int $length
     * @return string
     */
    public function ellipsisDescription($description, $length = 238)
    {
        $meta_description = str_replace(array("\r\n", "\n", "\r"), '', $description);
        return mb_strimwidth($meta_description, 0, $length, "…", "UTF-8");
    }
 
    /**
     * ページングに応じてページ数を追加して返す
     *
     * @param $title
     * @param $page
     * @return string
     */
    public function addPageNum($title, $page)
    {
        if ( !empty($page) && $page > 1 ) {
            return $title . "({$page}ページ目)";
        }
        return $title;
    }
 
    /**
     * 試し読み最新号を取得
     * @return bool
     */
    public function sideMagazineContents()
    {
        $magazine_content = Contents::findFirst(
            array(
                "conditions" =>
                    "
                    status = :status: and
                    type = :type: and
                    :now: between release_date and expiration_date
                    ",
                "bind" => array(
 
                    "status" => Contents::CONTENTS_STATUS_RELESE,
                    "type" => Contents::CONTENTS_TYPE_BOOK,
                    "now" => date('Y-m-d H:i:s'),
                ),
                "order" => "release_date DESC, created_at DESC",
            )
        );
 
        if ( !$magazine_content ) {
            return null;
        }
 
        $this->view->magazine_content = $magazine_content;
    }
 
    public function getContentPointsByContentsId($contents_id)
    {
        $builder = $this->modelsManager->createBuilder();
        return $builder->columns(array('body'))
            ->from('ContentPoints')
            ->where('deleted = :deleted:', array('deleted' => ModelBase::ACTIVE_PARAM))
            ->andWhere('content_id = :content_id:', array('content_id' => $contents_id))
            ->getQuery()->execute();
    }
 
    /**
     * インフィニティで掲出する次の記事URLを取得
     *
     * @param $base_content_id
     * @param $scroll_count
     * @param null $target_category
     * @return striing
     */
    public function getNextInfiniteArticleUrl($base_content_id, $scroll_count, $target_category = null)
    {
        // ファッションまとめは同一カテゴリの記事をインフィニティで掲出するが、基本的には除外カテゴリー扱いとする
        if ( $target_category != $this->categories_cache['url']['f-matome']['id'] ) {
            // 除外するカテゴリーの設定
            $remove_target_categories = array('photo', 'l-matome', 'f-matome', 'b-matome', 'o-matome');
            $remove_category_ids = array();
            foreach ( $remove_target_categories as $parent_category ) {
                $parent_id = $this->categories_cache['url'][$parent_category]['id'];
                $remove_category_ids[] = $parent_id;
                //サブカテが存在すればサブカテも除外する
                if ( isset($this->categories_cache['parent_categories_id'][$parent_id]) ) {
                    foreach ( $this->categories_cache['parent_categories_id'][$parent_id] as $sub_category ) {
                        $remove_category_ids[] = $sub_category['id'];
                    }
                }
            }
        }
 
        $query = $this->modelsManager->createBuilder()
            ->from('Contents')
            ->where('status = :status:', array('status' => Contents::CONTENTS_STATUS_RELESE))
            ->andWhere('deleted = :deleted:', array('deleted' => ModelBase::NOT_DELETED))
            ->andWhere('id != :base_content_id:', array('base_content_id' => $base_content_id))
            ->andWhere(':now: BETWEEN release_date AND expiration_date', array('now' => date('Y-m-d H:i:s')))
            ->orderBy('release_date DESC, id ASC')
            ->limit(1)
            ->offset($scroll_count);
 
        if ( empty($target_category) ) {
            $query->andWhere('categories_id NOT IN (' . implode(',', $remove_category_ids) . ')');
        }
 
        $query = $this->setConditions($target_category, $query);
        $content = $query->getQuery()->execute()->getFirst();
        return $this->mytag->content_url($content, $this->categories_cache);
    }
 
    /**
     * 対象カテゴリ毎にcontentTypeを指定
     * @param $target_category
     * @param $query
     * @return mixed
     */
    private function setConditions($target_category, $query)
    {
        if ( $target_category === $this->categories_cache['url']['morehapi_category']['id'] ) {
            $query->andWhere('type = :content_type:', array('content_type' => Contents::CONTENTS_TYPE_MOREHAPI));
            return $query;
        }
 
        $query->andWhere('type = :content_type:', array('content_type' => Contents::CONTENTS_TYPE_NEWS));
        if ( !empty($target_category) ) {
            $query->andWhere('categories_id = :category_id: OR mark = :mark:', array('category_id' => $target_category, 'mark' => Contents::CONTENTS_MARK_SPECIAL));
        }
        return $query;
    }
 
    /**
     * Feature枠用の記事をランダムで取得(CMSで設定)
     *
     * @return object 取得した記事情報
     */
    public function sideFeatureContents()
    {
        $param = array(
            'conditions' =>
                'status = :status: AND
                 type = :type: AND
                 :now: between release_date and expiration_date
                 ',
            'bind' => array(
                'status' => Links::LINKS_STATUS_RELESE,
                'type' => Links::LINKS_TYPE_FEATURE,
                'now' => date('Y-m-d H:i:s'),
            ),
            'order' => 'RAND()',
            'cache' => array(
                'key' => __FUNCTION__ . $this->device,
                'lifetime' => $this->config->models->cacheLifetime10min
            ),
        );
 
        if ( $this->device == self::DEVICE_SP ) {
            $device_type = Links::LINKS_DEVICE_TYPE_DEFAULT . "," . Links::LINKS_DEVICE_TYPE_SP;
            $param['conditions'] .= "AND device_type IN ({$device_type})";
        } else {
            $device_type = Links::LINKS_DEVICE_TYPE_DEFAULT . "," . Links::LINKS_DEVICE_TYPE_PC;
            $param['conditions'] .= "AND device_type IN ({$device_type})";
        }
 
        $this->view->side_feature_contents = Links::find($param);
    }
 
    /**
     * description用に記事ブロック全体から
     * 見出しブロックとHTMLテキストブロックのみ抽出して返す
     *
     * @param $content_blocks 記事ブロック
     * @return array
     */
    public function getContentsBodyForMeta($content_blocks)
    {
        $contents_bodys = '';
        $content_blocks->filter(function ($r) use (&$contents_bodys) {
            if ( $r->type == ContentBlocks::CONTENTBLOCKS_TYPE_TITLE ) {
                $contents_bodys .= $r->title;
            }
            if ( $r->type == ContentBlocks::CONTENTBLOCKS_TYPE_TEXT
                || $r->type == ContentBlocks::CONTENTBLOCKS_TYPE_HTML
                || $r->type == ContentBlocks::CONTENTBLOCKS_TYPE_IMAGE ) {
                $contents_bodys .= strip_tags($r->body);
            }
        });
        return $contents_bodys;
    }
}
 
?>
#5SiteControllerBase->getNextInfiniteArticleUrl(32542, 0, 68)
<?php
 
use Phalcon\Paginator\Adapter\Model as Paginator;
 
class SiteMorehapiController extends SiteControllerBase
{
 
    const ETC_CATEGORY = 'etc_news';
    const LIFE_STYLE_CATEGORY = 'odekake_news';
 
    public function initialize()
    {
        parent::initialize();
        $this->view->etc_category = self::ETC_CATEGORY;
        $this->breadcrumb['cat_top']['name'] = 'モアハピ部';
        $this->view->breadcrumb = $this->breadcrumb;
    }
 
    public function indexAction()
    {
        $limit = 15;
        $contents = $this->fetch_morehapi_new_contents($limit);
        $this->view->contents = $contents;
 
        $limit = 6;
        $user_ranking = $this->fetch_morehapi_user_ranking($limit);
        $this->view->user_ranking = $user_ranking;
 
        $limit = 6;
        $article_ranking = $this->fetch_morehapi_article_ranking($limit);
        $this->view->article_ranking = $article_ranking;
 
        //TODO:並び順確認(NoはCMSから削除してもらう!?その場合ソート機能が必要)
        $morehapi_all_member = $this->getMorehapiMember();
        $this->view->morehapi_all_member = $morehapi_all_member;
 
        //meta情報
        foreach ( $contents as $content ) {
            $option['image'] = $this->config->application->imageUrl . \Phalcon\Tag\MyTags::upimage_url($content->image);
            break;
        }
        $option['keywords'] = $this->meta_settings->keywords_list->morehapi;
        $this->setMetaTag('morehapi', 'morehapi_top', $option);
    }
 
    public function category_topAction()
    {
        $category_top_url = $this->dispatcher->getParam("cattop");
 
        //有効なカテゴリかチェック
        $blog_url_list = [];
        $morehapi_second_layer_categories = $this->categories_cache['parent_categories_id'][$this->categories_cache['url']['morehapi_category']['id']];
        foreach ( $morehapi_second_layer_categories as $second_layer_category ) {
            $blog_url_list[] = $second_layer_category['url'];
 
            //下位のカテゴリも考慮する
            $third_layer_categories = $this->categories_cache['parent_categories_id'][$this->categories_cache['url'][$second_layer_category['url']]['id']];
            if ( !empty($third_layer_categories) ) {
                foreach ( $third_layer_categories as $third_layer_category ) {
                    $blog_url_list[] = $third_layer_category['url'];
                }
            }
 
        }
 
        if ( in_array($category_top_url, $blog_url_list) === false && $category_top_url !== self::LIFE_STYLE_CATEGORY ) {
            return $this->return404();
        }
 
        $this->view->category_top_url = $category_top_url;
 
        // ページャー
        $numberPage = $this->request->getQuery("page", "int", 1);
 
        if ( $category_top_url === self::LIFE_STYLE_CATEGORY ) {
            $meta_option['description'] = $this->meta_settings->subcat_meta_info->morehapi->odekake_news->description;
            $cattop_name = 'ライフスタイル';
 
            $limit = null;
            $life_style_categories = [$this->categories_cache['url']['g-news']['id'], $this->categories_cache['url']['w-news']['id'], $this->categories_cache['url']['e-news']['id']];
            $contents = $this->fetch_morehapi_new_contents($limit, $life_style_categories);
        } else {
            $meta_option['title'] = $this->categories_cache['url'][$category_top_url]['name'];
            $meta_option['description'] = str_replace('{CATEGORY_NAME}', $this->categories_cache['url'][$category_top_url]['name'], $this->meta_settings->subcat_meta_info->morehapi->default->description);
            $cattop_name = $this->categories_cache['url'][$category_top_url]['name'];
 
            $limit = null;
            $category_id = $this->categories_cache['url'][$category_top_url]['id'];
            $contents = $this->fetch_morehapi_new_contents($limit, $category_id);
        }
 
        if ( count($contents) != 0 ) {
            $paginator = new Paginator(array(
                "data" => $contents,
                "limit" => 21,
                "page" => $numberPage,
            ));
 
            $this->view->page = $paginator->getPaginate();
        }
 
        $third_layer_categories = $this->categories_cache['parent_categories_id'][$this->categories_cache['url'][$category_top_url]['id']];
        $this->view->sub_categories = $third_layer_categories;
 
        if ( !empty($third_layer_categories) ) {
 
            foreach ( $third_layer_categories as $third_layer_category ) {
                $limit = 3;
                $third_layer_category_contents[$third_layer_category['url']] = $this->fetch_morehapi_new_contents($limit, $third_layer_category['id']);
            }
 
            $this->view->sub_categories_contents = $third_layer_category_contents;
        }
 
        $this->view->cattop_name = $cattop_name;
 
        //別カテゴリへの導線(プルダウン)
        $morehapi_link_url_list = $this->create_categories_link($morehapi_second_layer_categories);
        $this->view->sub_cate_list = $morehapi_link_url_list;
 
        //meta情報
        foreach ( $contents as $content ) {
            $meta_option['image'] = $this->config->application->imageUrl . \Phalcon\Tag\MyTags::upimage_url($content->image);
            break;
        }
        $meta_option['keywords'] = $this->meta_settings->keywords_list->morehapi;
        $this->setMetaTag('morehapi', 'morehapi', $meta_option, $numberPage);
 
        $this->breadcrumb['sub_cat_top']['name'] = $this->categories_cache['url'][$category_top_url]['name'] . '';
        $this->view->breadcrumb = $this->breadcrumb;
    }
 
    public function newsAction()
    {
        // ページャー
        $numberPage = $this->request->getQuery("page", "int", 1);
 
        //別カテゴリへの導線(プルダウン)
        $morehapi_second_layer_categories = $this->categories_cache['parent_categories_id'][$this->categories_cache['url']['morehapi_category']['id']];
        $morehapi_link_url_list = $this->create_categories_link($morehapi_second_layer_categories);
        $this->view->sub_cate_list = $morehapi_link_url_list;
 
        $limit = null;
        $contents = $this->fetch_morehapi_new_contents($limit);
 
        if ( count($contents) != 0 ) {
            $paginator = new Paginator(array(
                "data" => $contents,
                "limit" => 21,
                "page" => $numberPage,
            ));
 
            $this->view->page = $paginator->getPaginate();
        }
 
        //meta情報
        foreach ( $contents as $content ) {
            $option['image'] = $this->config->application->imageUrl . \Phalcon\Tag\MyTags::upimage_url($content->image);
            break;
        }
        $option['title'] = '最新情報';
        $option['description'] = $this->meta_settings->subcat_meta_info->morehapi->news->description;
        $option['keywords'] = $this->meta_settings->keywords_list->morehapi;
        $this->setMetaTag('morehapi', 'morehapi', $option, $numberPage);
 
        $this->breadcrumb['sub_cat_top']['name'] = '最新記事';
        $this->view->breadcrumb = $this->breadcrumb;
    }
 
    public function rankingAction()
    {
 
        $this->view->ranking_type = $type = $this->request->getQuery('type');
 
        // ページャー
        $numberPage = $this->request->getQuery("page", "int", 1);
 
        $paginatorLimit = 12;
        $this->view->ranking_startpoint = ($numberPage - 1) * $paginatorLimit;
 
        //ユーザーランキング
        if ( isset($type) && $type === 'user' ) {
 
            $limit = 20;
            $rankings = $this->fetch_morehapi_user_ranking($limit);
 
            //記事ランキング
        } else {
 
            $selected_category = $this->request->getQuery("category", "string", "all");
            $this->view->selected_category = $selected_category;
 
            $sub_categories = $this->categories_cache['parent_categories_id'][$this->categories_cache['url'][$selected_category]['id']];
 
            $limit = 20;
            $rankings = $this->fetch_morehapi_article_ranking($limit, $selected_category, $sub_categories);
 
            $morehapi_second_layer_categories = $this->categories_cache['parent_categories_id'][$this->categories_cache['url']['morehapi_category']['id']];
 
            foreach ( $morehapi_second_layer_categories as $key => $value ) {
                $key_sort[$key] = $value['sort'];
                $key_id[$key] = $value['id'];
            }
            array_multisort($key_sort, SORT_ASC, $key_id, SORT_ASC, $morehapi_second_layer_categories);
 
            $morehapi_link_url_list = [];
            $morehapi_link_url_list['all']['url'] = 'morehapi/ranking';
            $morehapi_link_url_list['all']['name'] = 'すべてのカテゴリ';
 
            foreach ( $morehapi_second_layer_categories as $sub_category ) {
 
                if ( $sub_category['url'] === self::ETC_CATEGORY ) {
                    continue;
                }
 
                $morehapi_link_url_list[$sub_category['url']]['url'] = 'morehapi/ranking?category=' . $sub_category['url'];
                $morehapi_link_url_list[$sub_category['url']]['name'] = $sub_category['name'];
 
            }
 
            $this->view->sub_cate_list = $morehapi_link_url_list;
 
        }
 
        if ( count($rankings) != 0 ) {
            $paginator = new Paginator(array(
                "data" => $rankings,
                "limit" => $paginatorLimit,
                "page" => $numberPage,
            ));
 
            $this->view->page = $paginator->getPaginate();
        }
 
        //meta情報
        $option['title'] = 'ランキング';
        $option['description'] = $this->meta_settings->subcat_meta_info->morehapi->ranking->description;
        $option['keywords'] = $this->meta_settings->keywords_list->morehapi;
        $this->setMetaTag('morehapi', 'morehapi', $option, $numberPage);
 
        $this->breadcrumb['sub_cat_top']['name'] = 'モアハピ部 ランキング';
        $this->view->breadcrumb = $this->breadcrumb;
    }
 
    /**
     * モアハピ部メンバー全取得
     * @return \Phalcon\Mvc\Model\ResultsetInterface
     */
    private function getMorehapiMember()
    {
        return Users::find(array(
            "conditions" =>
                "blog_status = :blog_status: and
                 blog_member_display = :blog_member_display: and
                 (blog_genre = :blog_genre_morehapi: or blog_genre = :blog_genre_premium:)",
            "bind" => array(
                "blog_status" => Users::USERS_BLOG_STATUS_RELESE,
                "blog_member_display" => Users::USERS_BLOG_MEMBER_DISPLAY_VALID,
                "blog_genre_morehapi" => Users::USERS_GENRE_MOREHAPI,
                "blog_genre_premium" => Users::USERS_GENRE_PREMIUM,
            ),
            "order" => "name,id",
            "cache" => [
                "key" => $this->create_cache_key('all_morehapi_member'),
                "lifetime" => $this->config->models->cacheLifetime3H
            ]
        ));
    }
 
    public function memberAction()
    {
        $users = $this->getMorehapiMember();
        $users_team = [];
        foreach ( $users as $user ) {
            if ( $user->blog_genre == Users::USERS_GENRE_MOREHAPI ) {
                $users_team['morehapi'][$user->blog_team][] = $user;
                continue;
            }
            if ( $user->blog_genre == Users::USERS_GENRE_PREMIUM ) {
                $users_team['premium'][] = $user;
                continue;
            }
        }
        $this->view->users = $users_team;
        $this->view->blog_team_list = Users::$blog_team_list;
 
        //meta情報
        $option['title'] = '部員一覧';
        $option['description'] = $this->meta_settings->subcat_meta_info->morehapi->member->description;
        $option['keywords'] = $this->meta_settings->keywords_list->morehapi;
        $this->setMetaTag('morehapi', 'morehapi', $option);
 
        $this->breadcrumb['sub_cat_top']['name'] = '部員一覧';
        $this->view->breadcrumb = $this->breadcrumb;
    }
 
    public function profileAction()
    {
        $blog_url = $this->dispatcher->getParam('blog_url');
 
        $user = Users::findFirst(array(
            "conditions" => "blog_url = :blog_url: and blog_status = :blog_status:",
            "bind" => array(
                "blog_url" => $blog_url,
                "blog_status" => Contents::CONTENTS_STATUS_RELESE,
            )
        ));
 
        if ( !$user ) {
            return $this->return404();
        }
 
        $this->view->user = $user;
 
        // ページャー
        $numberPage = $this->request->getQuery("page", "int", 1);
 
        $limit = null;
        $category_id = null;
        $contents = $this->fetch_morehapi_new_contents($limit, $category_id, $user->id);
 
        if ( count($contents) != 0 ) {
            $paginator = new Paginator(array(
                "data" => $contents,
                "limit" => 15,
                "page" => $numberPage,
            ));
 
            $this->view->page = $paginator->getPaginate();
        }
 
        //meta情報
        $option['title'] = $user->blog_title;
        $option['description'] = $this->meta_settings->subcat_meta_info->morehapi->member->description;
        $option['keywords'] = $this->meta_settings->keywords_list->morehapi;
        $this->setMetaTag('morehapi', 'morehapi', $option, $numberPage);
 
        $this->breadcrumb['sub_cat_top']['name'] = $user->blog_user_name;
        $this->breadcrumb['sub_cat_top']['uri'] = $this->breadcrumb['cat_top']['uri'] . '/account/' . $user->blog_url;
        $this->view->breadcrumb = $this->breadcrumb;
    }
 
    public function articleAction($contents_id)
    {
        $this->view->ad_category = 'article';
 
        $blog_url = $this->dispatcher->getParam('blog_url');
        $category_url = $this->dispatcher->getParam('category_url');
        $contentPage = $this->dispatcher->getParam('page');
 
        $user = Users::findFirst(array(
            "blog_url = :blog_url:",
            "bind" => array('blog_url' => $blog_url),
        ));
 
        $this->view->user = $user;
 
        $content = Contents::findFirst(array(
            "conditions" =>
                "users_id = :users_id: and
                id = :id: and
                status = :status: and
                type = :type: and
                :now: between release_date and expiration_date
                ",
            "bind" => array(
                "users_id" => $user->id,
                "id" => $contents_id,
                "status" => Contents::CONTENTS_STATUS_RELESE,
                "type" => Contents::CONTENTS_TYPE_MOREHAPI,
                "now" => date('Y-m-d H:i:s'),
            ),
 
        ));
 
        if ( empty($content->id) ) {
            return $this->return404();
        }
 
        $content_category_url = $this->categories_cache['id'][$content->categories_id]['url'];
 
        if ( $content_category_url !== $category_url ) {
            return $this->return404();
        }
 
        $this->view->content = $content;
 
        $this->view->content_points = $this->getContentPointsByContentsId($contents_id);
 
        $this->view->content_blocks = $content_blocks = ContentBlocks::find(array(
            'conditions' => "contents_id = :contents_id: and type != :type:",
            'bind' => array('contents_id' => $contents_id, 'type' => ContentBlocks::CONTENTBLOCKS_TYPE_SLIDER_IMAGE),
            'order' => "sort, id",
        ));
        $this->view->slider_image_blocks = ContentBlocks::find(array(
            'conditions' => "contents_id = :contents_id: and type = :type:",
            'bind' => array('contents_id' => $contents_id, 'type' => ContentBlocks::CONTENTBLOCKS_TYPE_SLIDER_IMAGE),
            'order' => "slider_group, sort, id",
        ));
        $this->view->type = ContentBlocks::$type_list;
 
        $around_contents = $this->getAroundContents($this->categories_cache['url'][$category_url]['id'], Contents::CONTENTS_TYPE_MOREHAPI, $content->release_date);
        $this->view->around_contents = $around_contents;
 
        $limit = 20;
        $category_id = null;
        $other_contents = $this->fetch_morehapi_new_contents($limit, $category_id, $user->id);
 
        if ( $other_contents->count() > 1 ) {
            $this->view->contents = $other_contents;
        }
 
        //モアハピ部カテゴリ別の最新記事
        $morehapi_second_layer_categories = $this->categories_cache['parent_categories_id'][$this->categories_cache['url']['morehapi_category']['id']];
 
        foreach ( $morehapi_second_layer_categories as $key => $value ) {
            $key_sort[$key] = $value['sort'];
            $key_id[$key] = $value['id'];
        }
        array_multisort($key_sort, SORT_ASC, $key_id, SORT_ASC, $morehapi_second_layer_categories);
 
        $category_contents = [];
        foreach ( $morehapi_second_layer_categories as $second_layer_category ) {
 
            if ( $second_layer_category['url'] === self::ETC_CATEGORY ) {
                continue;
            }
 
            $limit = 4;
            $category_id = $this->categories_cache['url'][$second_layer_category['url']]['id'];
            $category_contents[$second_layer_category['url']] = $this->fetch_morehapi_new_contents($limit, $category_id);
        }
        $this->view->category_contents = $category_contents;
        $this->view->area_waku = $this->getAreaLinks();
 
        $meta_description = $user->blog_title;
        $contents_body = $this->getContentsBodyForMeta($content_blocks);
        if ( !empty($contents_body) ) {
            $meta_description = $this->ellipsisDescription($contents_body);
        }
 
        $this->view->scroll_count = $scroll_count = $this->request->getQuery('scroll', 'int', 0);
        $this->view->infinite_category = null;
        $this->view->base_content_id = $base_content_id = $this->request->getQuery('base_content_id', 'int', $contents_id);
        $this->view->next_url = $this->getNextInfiniteArticleUrl($base_content_id, $scroll_count, $this->categories_cache['url']['morehapi_category']['id']);
        $content_title = $this->addPageNum($content->title, $contentPage);
        $this->tag->prependTitle(htmlspecialchars($content_title) . " | " . $this->meta_settings->middle_title->morehapi);
        $this->meta['keywords'] = $this->meta_settings->keywords_list->morehapi;
        $this->meta['description'] = $meta_description . " | DAILY MORE";
        $this->og['title'] = $content_title;
        $this->og['image'] = \Phalcon\Tag\MyTags::upimage_url($content->image);
        $this->og['description'] = $this->meta['description'];
        $this->og['type'] = 'article';
        $this->view->meta = $this->meta;
        $this->view->og = $this->og;
        $this->view->popin_view_scroll_num = self::POPIN_VIEW_SCROLL_NUM;
        $this->view->logly_view_scroll_num = self::LOGLY_VIEW_SCROLL_NUM;
        $this->view->shopping_view_scroll_num = self::SHOPPING_VIEW_SCROLL_NUM;
 
        $this->breadcrumb['sub_cat_top']['name'] = $user->blog_user_name;
        $this->breadcrumb['sub_cat_top']['uri'] = $this->breadcrumb['cat_top']['uri'] . '/account/' . $user->blog_url;
        $this->breadcrumb['article']['name'] = $content->title;
        $this->breadcrumb['article']['uri'] = $this->mytag->content_url($content, $this->categories_cache);
        $this->view->breadcrumb = $this->breadcrumb;
    }
 
    private function fetch_morehapi_user_ranking($limit = null)
    {
 
        $phql = "
            SELECT
                Users.blog_url as users_blog_url,
                Users.blog_url_image as users_blog_url_image,
                Users.name as users_name,
                SUM(Contents.monthly_pageview) as pv_total
            FROM
                Contents, Users
            WHERE
                Contents.users_id = Users.id AND
                Contents.status = :status: AND
                Contents.type = :type: AND
                :now: BETWEEN Contents.release_date AND Contents.expiration_date AND
                Contents.deleted = :deleted: AND
                Users.blog_status = :blog_status: AND 
                Users.blog_member_display = :blog_member_display:
            GROUP BY
                Users.id
            ORDER BY
                pv_total DESC
            ";
 
        $add_query = "";
        if ( !empty($limit) ) {
            $add_query .= " LIMIT " . $limit;
        }
 
        $query = $this->modelsManager->createQuery($phql . $add_query);
 
        $query->cache([
            'key' => $this->create_cache_key(__FUNCTION__, $limit),
            'lifetime' => $this->config->models->cacheLifetime3H
        ]);
 
        $user_ranking = $query->execute(
            [
                "status" => Contents::CONTENTS_STATUS_RELESE,
                "type" => Contents::CONTENTS_TYPE_MOREHAPI,
                "now" => date('Y-m-d H:i:s'),
                "deleted" => ModelBase::NOT_DELETED,
                "blog_status" => Users::USERS_BLOG_STATUS_RELESE,
                "blog_member_display" => Users::USERS_BLOG_MEMBER_DISPLAY_VALID,
            ]
        );
 
        return $user_ranking;
 
    }
 
    private function fetch_morehapi_article_ranking($limit = null, $selected_category = 'all', $sub_categories = null)
    {
        $phql = "
            SELECT
                Contents.id,
                Contents.title,
                Contents.categories_id,
                Contents.mark,
                Contents.release_date,
                Contents.image_rectangle,
                Contents.image_thumbnail,
                Contents.type,
                Users.blog_url AS users_blog_url,
                Users.name AS users_name
            FROM
                Contents, Users
            WHERE
                Contents.users_id = Users.id AND
                Contents.status = :status: AND
                Contents.type = :type: AND
                Contents.deleted = :deleted: AND
                Users.blog_status = :blog_status: AND
                :now: BETWEEN Contents.release_date AND Contents.expiration_date AND
                Contents.release_date > :border:
            ";
 
        $cache_name = __FUNCTION__;
        if ( !empty($sub_categories) ) {
 
            $categories_id[] = $this->categories_cache['url'][$selected_category]['id'];
            foreach ( $sub_categories as $sub_category ) {
                $categories_id[] = $sub_category['id'];
            }
 
            $phql .= " and Contents.categories_id IN (" . implode(',', $categories_id) . ")";
            $cache_name .= '_categories';
        }
 
        if ( empty($sub_categories) && $selected_category !== 'all' ) {
            $phql .= " and Contents.categories_id = " . $this->categories_cache['url'][$selected_category]['id'];
            $cache_name .= '_category';
        }
 
        $phql .= " ORDER BY Contents.monthly_pageview DESC";
 
        if ( !empty($limit) ) {
            $phql .= " LIMIT " . $limit;
        }
 
        $query = $this->modelsManager->createQuery($phql);
 
        $query->cache(
            [
                'key' => $this->create_cache_key($cache_name, [$categories_id, $this->categories_cache['url'][$selected_category]['id'], $limit]),
                'lifetime' => $this->config->models->cacheLifetime3H
            ]
        );
 
        $article_ranking = $query->execute(
            [
                "status" => Contents::CONTENTS_STATUS_RELESE,
                "type" => Contents::CONTENTS_TYPE_MOREHAPI,
                "deleted" => ModelBase::NOT_DELETED,
                "blog_status" => Users::USERS_BLOG_STATUS_RELESE,
                "now" => date('Y-m-d H:i:s'),
                "border" => date("Y-m-d H:i:s", strtotime("-1 month"))
            ]
        );
 
        return $article_ranking;
    }
 
    private function create_categories_link($morehapi_second_layer_categories)
    {
        //別カテゴリへの導線(プルダウン)
        $morehapi_base_url = 'morehapi/';
        foreach ( $morehapi_second_layer_categories as $key => $value ) {
            $key_sort[$key] = $value['sort'];
            $key_id[$key] = $value['id'];
        }
        array_multisort($key_sort, SORT_ASC, $key_id, SORT_ASC, $morehapi_second_layer_categories);
 
        $morehapi_link_url_list = [];
        $morehapi_link_url_list['all']['url'] = $morehapi_base_url . 'news';
        $morehapi_link_url_list['all']['name'] = 'すべてのカテゴリ';
 
        foreach ( $morehapi_second_layer_categories as $category ) {
 
            if ( $category['url'] === self::ETC_CATEGORY ) {
                continue;
            }
            $morehapi_link_url_list[$category['url']]['url'] = $morehapi_base_url . $category['url'];
            $morehapi_link_url_list[$category['url']]['name'] = $category['name'];
 
        }
        return $morehapi_link_url_list;
    }
}
 
#6SiteMorehapiController->articleAction(32542, asu, g-news)
#7Phalcon\Dispatcher->dispatch()
#8Phalcon\Mvc\Application->handle()
<?php
 
// if ($_SERVER["REQUEST_URI"] != "/") {
//   switch (true) {
//     case !isset($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']):
//     case $_SERVER['PHP_AUTH_USER'] !== 'morestaff':
//     case $_SERVER['PHP_AUTH_PW'] !== '0327onair':
//       header('WWW-Authenticate: Basic realm="Enter username and password."');
//       header('Content-Type: text/plain; charset=utf-8');
//       die('このページを見るにはログインが必要です');
//   }
 
//   header('Content-Type: text/html; charset=utf-8');
 
// }
 
mb_internal_encoding("UTF-8");
 
error_reporting(0);
 
 $debug = new \Phalcon\Debug();
 $debug->setUri('http://static.phalconphp.com/debug/2.0.0/');
 $debug->listen();
 
//try {
 
/**
 * Read the configuration
 */
$config = new \Phalcon\Config\Adapter\Ini(__DIR__ . "/../app/config/config.ini");
 
/**
 * Read auto-loader
 */
include __DIR__ . "/../app/config/loader.php";
 
/**
 * Read the route setting
 */
$route = include __DIR__ . "/../app/config/route.php";
 
/**
 * Read services
 */
include __DIR__ . "/../app/config/services.php";
 
/**
 * Handle the request
 */
$application = new \Phalcon\Mvc\Application($di);
 
echo $application->handle()->getContent();
 
//} catch (\Exception $e) {
//    echo $e->getMessage();
//    $response = new \Phalcon\Http\Response();
//    $response->setStatusCode(503, "Service Unavailable");
//    $html=file_get_contents("http://d1fu8lafwdn865.cloudfront.net/upload/503.html");
//    if($html){
//        $response->setContent($html);
//    }else{
//        $response->setContent("<div style='text-align: center'><p>ただいまアクセスが集中し、つながりにくい状態です。</p><p>誠に申し訳ございませんが、しばらく時間をおいてから再度ご利用ください。</p></div>");
//    }
//    $response->send();
//}
KeyValue
_url/morehapi/article/asu/g-news/32542
KeyValue
REDIRECT_STATUS200
HTTP_HOSTmore.hpplus.jp
HTTP_ACCEPTtext/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
HTTP_ACCEPT_ENCODINGgzip
HTTP_INCAP_CLIENT_IP54.82.73.21
HTTP_INCAP_PROXY_237OK
HTTP_USER_AGENTCCBot/2.0 (https://commoncrawl.org/faq/)
HTTP_X_UA_DEVICEpc
HTTP_X_VARNISH976847324
HTTP_X_FORWARDED_FOR54.82.73.21, 198.143.37.4, 127.0.0.1, 127.0.0.1, 52.196.127.209
HTTP_X_FORWARDED_PORT443
HTTP_X_FORWARDED_PROTOhttps
HTTP_CONNECTIONkeep-alive
PATH/sbin:/usr/sbin:/bin:/usr/bin
SERVER_SIGNATURE
SERVER_SOFTWAREApache/2.4.12 (Amazon) PHP/5.5.24
SERVER_NAMEmore.hpplus.jp
SERVER_ADDR10.1.21.115
SERVER_PORT80
REMOTE_ADDR10.1.12.153
DOCUMENT_ROOT/home/ec2-user/www2/dailymore/public
REQUEST_SCHEMEhttp
CONTEXT_PREFIX
CONTEXT_DOCUMENT_ROOT/home/ec2-user/www2/dailymore/public
SERVER_ADMINroot@localhost
SCRIPT_FILENAME/home/ec2-user/www2/dailymore/public/index.php
REMOTE_PORT4576
REDIRECT_QUERY_STRING_url=/morehapi/article/asu/g-news/32542
REDIRECT_URL/morehapi/article/asu/g-news/32542
GATEWAY_INTERFACECGI/1.1
SERVER_PROTOCOLHTTP/1.1
REQUEST_METHODGET
QUERY_STRING_url=/morehapi/article/asu/g-news/32542
REQUEST_URI/morehapi/article/asu/g-news/32542
SCRIPT_NAME/index.php
PHP_SELF/index.php
REQUEST_TIME_FLOAT1542203322.222
REQUEST_TIME1542203322
#Path
0/home/ec2-user/www2/dailymore/public/index.php
1/home/ec2-user/www2/dailymore/app/config/loader.php
2/home/ec2-user/www2/dailymore/app/config/route.php
3/home/ec2-user/www2/dailymore/app/config/services.php
4/home/ec2-user/www2/dailymore/app/controllers/SiteMorehapiController.php
5/home/ec2-user/www2/dailymore/app/controllers/SiteControllerBase.php
6/home/ec2-user/www2/dailymore/app/controllers/ControllerBase.php
7/home/ec2-user/www2/dailymore/app/config/meta_settings.php
8/home/ec2-user/www2/dailymore/app/models/Categories.php
9/home/ec2-user/www2/dailymore/app/models/ModelBase.php
10/home/ec2-user/www2/dailymore/app/models/Contents.php
11/home/ec2-user/www2/dailymore/app/models/Links.php
12/home/ec2-user/www2/dailymore/app/config/newslink_settings.php
13/home/ec2-user/www2/dailymore/app/models/Users.php
14/home/ec2-user/www2/dailymore/app/models/ContentPoints.php
15/home/ec2-user/www2/dailymore/app/models/ContentBlocks.php
Memory
Usage3670016