导航菜单

网上各种typecho二次开发实例都是自定义函数,调用方式都是方法调用,和Typecho的调调不太符合,所以看了一下Typecho代码写了这个类,方便各位主题作者使用。
增加了排序,分类,模板查询处理
没有做分页处理

<?php if (!defined('__TYPECHO_ROOT_DIR__')) {
/**
 * @Author: Ryan<github-benzbrake@woai.ru>
 * @Date: 2020-03-07 15:41:33
 * @LastEditors: Ryan
 * @LastEditTime: 2020-03-26 16:53:12
 * @Description: Widget类
 * @FilePath     : \po\libs\Widget.php
 */
    exit;
}

/* 文章查询增强 */
class XMP_Post_Query extends Widget_Abstract_Contents
{
    /**
     * 分页计算对象
     *
     * @access private
     * @var Typecho_Db_Query
     */
    private $_countSql;

    /**
     * 所有文章个数
     *
     * @access private
     * @var integer
     */
    private $_total = false;
    /**
     * 设置分页对象
     *
     * @access private
     * @var Typecho_Widget_Helper_PageNavigator
     */
    public function __construct($request, $response, $params = null)
    {
        parent::__construct($request, $response, $params);
    }
    /**
     * 获取 SQL 查询对象
     *
     * @return Typecho_Db_Query
     */
    public function select()
    {
        return parent::select()->where('table.contents.type = ?', 'post')->where('status = ?', 'publish')->where('table.contents.created <= ?', time())->limit($this->parameter->pageSize)->join('table.relationships', 'table.relationships.cid = table.contents.cid')->join('table.metas', 'table.relationships.mid = table.metas.mid')->where('table.metas.type=?', 'category');
    }

    public function execute()
    {
        /** 避免重复取数据 */
        if ($this->have()) {
            return;
        }

        /** select 初始化 */
        $select = $this->select();
        // 过滤文章分类
        if (isset($this->parameter->mid) && ($this->parameter->mid !== "")) {
            $params = $this->__divideStrToArr($this->parameter->mid);
            if (count($params['in']) > 0) {
                $select = $select->where('table.relationships.mid in (?)', implode(",", $params['in']));
            }
            foreach ($params['notin'] as $param) {
                $select = $select->where('table.relationships.mid <> ?', $param);
            }
        }
        // 过滤文章类型
        if (isset($this->parameter->postTemplate) && ($this->parameter->postTemplate !== "")) {
            $params = $this->__divideStrToArr($this->parameter->postTemplate);
            foreach ($params['notin'] as $param) {
                // 2020.03.13 Fix default post was filtered
                $select = $select->where('table.contents.template <> ? or table.contents.template is null', $param);
            }
            if (count($params['in']) > 0) {
                $select = $select->where('table.contents.template in (?)', implode(",", $params['in']));
            }
        }

        // 排序
        $select = $select->order('table.contents.created', Typecho_Db::SORT_DESC);
        if (isset($this->parameter->listOrder)) {
            if (strtolower($this->parameter->listOrder) === "random") {
                $adapterName = $this->db->getAdapterName();
                if ($adapterName == 'pgsql' || $adapterName == 'Pdo_Pgsql' || $adapterName == 'Pdo_SQLite' || $adapterName == 'SQLite') {
                    $order_by = 'RANDOM()';
                } else {
                    $order_by = 'RAND()';
                }
                $select = $select->order($order_by);
            } elseif (strtolower($this->parameter->listOrder) === "asc") {
                $select = $select->order('table.contents.created', Typecho_Db::SORT_ASC);
            }
        }
        $this->_countSql = clone $select;
        $this->db->fetchAll($select, array($this, 'push'));
    }
    /**
     * 获取文章描述
     *
     * @param integer $length
     * @param string $trim
     * @return void
     */
    public function __excerpt($length = 50, $trim = '...')
    {
        return Typecho_Common::subStr(strip_tags($this->content), 0, $length, $trim);
    }
    /**
     * 获取浏览次数
     *
     * @param string $format0
     * @param string $format1
     * @param string $formats
     * @return String
     */
    public function __views($format0 = "0 次浏览", $format1 = "1 次浏览", $formats = "%s 次浏览")
    {
        $fields = unserialize($widget->fields);
        if (array_key_exists('views', $fields)) {
            $views = (!empty($fields['views'])) ? intval($fields['views']) : 0;
        } else {
            $views = 0;
            return sprintf($format0, $views);
        }
        if ($views = 1) {
            return sprintf($format1, $views);
        }
        return sprintf($formats, $views);
    }
    /**
     * @description 过滤参数
     * @param array $value
     * @return array $value
     */
    public function filter($value)
    {
        $value = parent::filter($value);
        return $value;
    }
    /**
     * @description 获取文章长度
     * @return int
     */
    public function getTotal()
    {
        if (false === $this->_total) {
            $this->_total = $this->size($this->_countSql);
        }

        return $this->_total;
    }
    /**
     * @description 按照格式转换输出
     * @param String $format
     * @return String
     */
    public function parse($format)
    {
        while ($this->next()) {
            echo preg_replace_callback("/\{([_a-z0-9]+)\}/i",
                array($this, '__parseCallback'), $format);
        }
    }
    protected function __parseCallback($matches)
    {
        // 处理部分关键字
        $this->excerpt = $this->__excerpt();
        $this->views = $this->__views();
        return $this->{$matches[1]};
    }
    /**
     * @description 配置字符串转数组
     * @param String $str
     * @return array
     */
    protected function __divideStrToArr($str)
    {
        $arr = array_unique(explode(",", $str));
        $arr1 = array();
        $arr2 = array();
        foreach ($arr as $value) {
            if (strpos($value, '-') === 0) { // Start with -
                array_push($arr1, substr($value, 1));
            } else {
                array_push($arr2, $value);
            }
        }
        return array("notin" => $arr1, "in" => $arr2);
    }
}

调用方式很简单,和调用自带的Widget_Abstract_Contents类差不多
最新文章:

Typecho->Widget::widget('XMP_Post_Query@index-newtest', 'pageSize=4&template=post-note.php')->to($post);

随机文章:

Typecho->Widget::widget('XMP_Post_Query@notfound_random', 'pageSize=5&listOrder=random&template=-post-note.php")->parse('<li class="post-list-item clearfix"><a class="cover float-left" href="{permalink}"></a><div class="post-list-body"><a href="{permalink}"><h3>{title}</h3></a><span class="views">{views}</span></div></li>')->to($posts)