Open-Source PHP Framework - Designed for rapid development of performance-oriented scalable applications

/mvc/models/wiki

[return to app]
1
<?php
/**
 * Manages Wiki data
 */
class wikiModel extends model {
    /**
     * Maximum number of search results to return
     *
     * @var int
     */
    public $searchLimit = 30;

    /**
     * Maximum length of search result descriptions
     *
     * @var int
     */
    public $maxSearchResultDescriptionLength = 200;

    /**
     * Establish the base location of the wiki
     *
     * @return string
     */
    protected function _getController() {
        $return = mvc::$controller;
        if (mvc::$action != 'index') {
            $return .= '/' . mvc::$action;
        }
        return $return;
    }

    /**
     * Retrieve the page data
     *
     * @param int $version Optional - if ommitted then most recent version will be used
     * @return array
     */
    public function select($version = null) {
        $sqlWhere = ' where controller=' . $this->db->cleanString($this->_getController())
                  . ' and wikiaction=' . $this->db->cleanString(mvc::$params[0]);
        $sql = 'select title, body, keywords, description'
             . (!$version ? ' from wikicache' : ', comments from wikilog') . $sqlWhere;
        if ($version) {
            $sql .= ' and version=' . $this->db->cleanString($version);
        }
        $res = $this->db->query($sql);
        if (!$res) {
            $this->initializeDb();
            $res = $this->db->query($sql);
        }
        $row = $res->fetch_assoc();
        if ($row) {
            $return = array('title' => $row['title'], 'body' => $row['body']);
            $return['head']['meta']['keywords'] = $row['keywords'];
            $return['head']['meta']['description'] = $row['description'];
            if ($version) {
                $return['comments'] = $row['comments'];
            }
        } else {
            $return = array('title' => '', 'body' => '', 'returncode' => 404);
            $sql = 'select version from wikilog ' . $sqlWhere . ' limit 1';
            $res = $this->db->query($sql);
            $return['hasHistory'] = $res->fetch_assoc();
        }
        return $return;
    }

    /**
     * Searches the wiki documents
     *
     * @param string $keyword
     * @return array
     */
    public function search($keyword) {
        $controller = $this->_getController();
        $keyword = "'%" . $this->db->{db::ESCAPE_STRING}($keyword) . "%'";
        $dbParents = class_parents($this->db);
        $isMysql = (isset($dbParents['mysqli']) || isset($dbParents['mysql']));
        //$this->maxSearchResultDescriptionLength + 150 accounts for up to 150 chars of inline HTML
        $description = (!$isMysql ? 'description' : "if(description != '', description, substring(body, 1, "
                                                    . ($this->maxSearchResultDescriptionLength + 150)
                                                    . ")) as description");
        $sql = 'select wikiaction, title, ' . $description . ' from wikicache where (body like ' . $keyword
             . ' or keywords like ' . $keyword . ' or description like ' . $keyword
             . ') and controller=' . $this->db->cleanString($controller);
        if ($isMysql) {
            $sql .= ' limit ' . $this->searchLimit;
        } else if (isset($dbParents['oci8'])) {
            $sql .= ' and rownum<=' . $this->searchLimit;
        } else if (isset($dbParents['mssql'])) {
            $sql = 'select top ' . $this->searchLimit . substr($sql, 6);
        }
        $res = $this->db->query($sql);
        while ($row = $res->fetch_assoc()) {
            $row['description'] = str_replace(array("\r\n", "\n", "\r", '  '), ' ',
 
strip_tags($row['description'])); if (strlen($row['description']) > $this->maxSearchResultDescriptionLength) { $row['description'] = substr($row['description'], 0, $this->maxSearchResultDescriptionLength); $lastSpace = strrpos($row['description'], ' '); if ($lastSpace) { $row['description'] = substr($row['description'], 0, $lastSpace); } $row['description'] .= '...'; } $return['/' . $controller . '/' . $row['wikiaction']] = $row; } return (isset($return) ? $return : array()); } /** * Update the wiki page data * * Uses MySQL/SQLite-specific replace-into syntax, other databases will need to adjust syntax * * @param array $data */ public function update(array $data) { $controller = $this->db->cleanString($this->_getController()); $wikiaction = $this->db->cleanString(mvc::$params[0]); $args = array('table' => 'wikilog', 'vals' => array_merge($this->db->cleanString($data), array('controller' => $controller, 'wikiaction' => $wikiaction, 'version' =>
 
'current_timestamp'))); $sql = $this->db->insertSql($args); $this->db->query($sql); $cols = 'controller, wikiaction, title, body, keywords, description'; $sql = 'replace into wikicache (' . $cols . ') select ' . $cols . ' from wikilog where controller=' . $controller . ' and wikiaction=' . $wikiaction . ' order by version desc limit 1'; $this->db->query($sql); } /** * Revert the wiki to a different version * * @param string $version database date/time */ public function revertToVersion($version) { $data = $this->select($this->_getController(), mvc::$params[0], $version); if ($data) { $data['comments'] = 'Reverted to version: ' . $version; $this->update($data); } } /** * Delete the wiki page */ public function delete() { $sql = 'delete from wikicache where controller=' . $this->db->cleanString($this->_getController()) . ' and wikiaction=' . $this->db->cleanString(mvc::$params[0]); $this->db->query($sql); } /** * Retrieve the list of changes made to a wiki page * * @return array */ public function getHistory() { $sql = 'select version, comments from wikilog where controller=' . $this->db->cleanString($this->_getController()) . ' and wikiaction=' . $this->db->cleanString(mvc::$params[0]) . ' order by version desc'; $res = $this->db->query($sql); while ($row = $res->fetch_assoc()) { $return[$row['version']] = $row['comments']; } return (isset($return) ? $return : array()); } /** * builds database tables automatically upon first usage * * If your database does not support the datetime and text column types then you will need to adjust this
 
method. * Oracle users may also swap varchar with varchar2 */ public function initializeDb() { $cols = 'controller varchar(100) not null, wikiaction varchar(50) not null, title varchar(255) not null, body text not null, keywords varchar(255) not null, description varchar(255) not null,'; $sql = 'create table wikicache (' . $cols . ' primary key(controller, wikiaction))'; $this->db->query($sql); $sql = 'create table wikilog (' . $cols . ' version datetime not null, comments varchar(255) null, primary key(controller, wikiaction, version))'; $this->db->query($sql); } }