Файл: library/XenForo/Model/Page.php
Строк: 411
<?php
class XenForo_Model_Page extends XenForo_Model
{
const PAGE_TEMPLATE_PREFIX = '_page_node.';
const FETCH_TEMPLATE = 0x01;
/**
* Constructs the title of the template that corresponds to a page.
*
* @param array $page
*
* @return string
*/
public function getTemplateTitle(array $page)
{
if (!isset($page['node_id']) || $page['node_id'] === '')
{
throw new XenForo_Exception('Input page array does not contain node_id');
}
return self::PAGE_TEMPLATE_PREFIX . $page['node_id'];
}
/**
* Fetches a single page record, as specified by the node ID
*
* @param integer $nodeId
* @param array $fetchOptions
*
* @return array|bool
*/
public function getPageById($nodeId, array $fetchOptions = array())
{
$joinOptions = $this->preparePageJoinOptions($fetchOptions);
return $this->_getDb()->fetchRow('
SELECT
node.*,
page.*
' . $joinOptions['selectFields'] . '
FROM xf_page AS page
INNER JOIN xf_node AS node ON (node.node_id = page.node_id)
' . $joinOptions['joinTables'] . '
WHERE node.node_id = ?
', $nodeId);
}
/**
* @param array $nodeIds
* @param array $fetchOptions
*
* @return array
*/
public function getPagesByIds(array $nodeIds, array $fetchOptions = array())
{
if (!$nodeIds)
{
return array();
}
$joinOptions = $this->preparePageJoinOptions($fetchOptions);
return $this->fetchAllKeyed('
SELECT node.*, page.*
' . $joinOptions['selectFields'] . '
FROM xf_page AS page
INNER JOIN xf_node AS node ON (node.node_id = page.node_id)
' . $joinOptions['joinTables'] . '
WHERE node.node_id IN (' . $this->_getDb()->quote($nodeIds) . ')
', 'node_id');
}
/**
* Fetches a single page record, as specified by the node name
*
* @param string $nodeName
* @param array $fetchOptions
*
* @return array|bool
*/
public function getPageByName($nodeName, array $fetchOptions = array())
{
$joinOptions = $this->preparePageJoinOptions($fetchOptions);
return $this->_getDb()->fetchRow('
SELECT node.*, page.*
' . $joinOptions['selectFields'] . '
FROM xf_page AS page
INNER JOIN xf_node AS node ON (node.node_id = page.node_id)
' . $joinOptions['joinTables'] . '
WHERE node.node_name = ?
', $nodeName);
}
/**
* Fetches all pages specified by the node names given
*
* @param array $nodeNames
* @param array $fetchOptions
*
* @return array
*/
public function getPagesByNames(array $nodeNames, $fetchOptions = array())
{
$joinOptions = $this->preparePageJoinOptions($fetchOptions);
return $this->fetchAllKeyed('
SELECT node.*, page.*
' . $joinOptions['selectFields'] . '
FROM xf_page AS page
INNER JOIN xf_node AS node ON (node.node_id = page.node_id)
' . $joinOptions['joinTables'] . '
WHERE node.node_name IN (' . $this->_getDb()->quote($nodeNames) . ')
', 'node_name');
}
/**
* Prepares page join options.
*
* @param array $fetchOptions
*
* @return array
*/
public function preparePageJoinOptions(array $fetchOptions)
{
$selectFields = '';
$joinTables = '';
$db = $this->_getDb();
if (!empty($fetchOptions['join']))
{
if ($fetchOptions['join'] & self::FETCH_TEMPLATE)
{
$selectFields .= ',
template.template AS content';
$joinTables .= '
LEFT JOIN xf_template AS template ON
(template.title = CONCAT(' . $db->quote(self::PAGE_TEMPLATE_PREFIX) . ', page.node_id) AND template.style_id = 0)';
}
}
if (!empty($fetchOptions['permissionCombinationId']))
{
$selectFields .= ',
permission.cache_value AS node_permission_cache';
$joinTables .= '
LEFT JOIN xf_permission_cache_content AS permission
ON (permission.permission_combination_id = ' . $db->quote($fetchOptions['permissionCombinationId']) . '
AND permission.content_type = 'node'
AND permission.content_id = page.node_id)';
}
return array(
'selectFields' => $selectFields,
'joinTables' => $joinTables
);
}
public function getPageContent($nodeId)
{
return strval($this->_getDb()->fetchOne('
SELECT template
FROM xf_template
WHERE title = ' . $this->_getDb()->quote(self::PAGE_TEMPLATE_PREFIX . $nodeId) . '
AND style_id = 0
'));
}
/**
* Gets pages IDs in the specified range. The IDs returned will be those immediately
* after the "start" value (not including the start), up to the specified limit.
*
* @param integer $start IDs greater than this will be returned
* @param integer $limit Number of posts to return
*
* @return array List of IDs
*/
public function getPageIdsInRange($start, $limit)
{
$db = $this->_getDb();
return $db->fetchCol($db->limit('
SELECT node_id
FROM xf_page
WHERE node_id > ?
ORDER BY node_id
', $limit), $start);
}
/**
* Determines if the specified page can be viewed with the given permissions.
*
* @param array $category Info about the category posting in
* @param string $errorPhraseKey Returned phrase key for a specific error
* @param array|null $nodePermissions List of permissions for this page; if not provided, use visitor's permissions
* @param array|null $viewingUser
*
* @return boolean
*/
public function canViewPage(array $page, &$errorPhraseKey = '', array $nodePermissions = null, array $viewingUser = null)
{
$this->standardizeViewingUserReferenceForNode($page['node_id'], $viewingUser, $nodePermissions);
return XenForo_Permission::hasContentPermission($nodePermissions, 'view');
}
/**
* Logs a visit by a user to a page
*
* @param array $page
* @param array $user
* @param integer $time
*/
public function logVisit(array $page, array $user, $time)
{
// TODO: bulk view updating like attachments/threads
$this->_getDb()->query('
UPDATE xf_page
SET view_count = view_count + 1
WHERE node_id = ?
', $page['node_id']);
}
/**
* Fetches all (visible) sibling nodes of the specified page
*
* @param array $page
* @param boolean $includeSelf Include self in results
*
* @return array Node list, plus routePrefix and href (public link) keys for each node
*/
public function getSiblingNodes(array $page, $includeSelf = true)
{
$nodes = $this->_getNodeModel()->getSiblingNodes($page, $includeSelf, true);
return $this->_prepareRelatedNodes($nodes);
}
/**
* Fetches all (visible) child nodes of the specified page
*
* @param array $page
*
* @return array
*/
public function getChildNodes(array $page)
{
$nodes = $this->_getNodeModel()->getChildNodesToDepth($page, 1, true);
return $this->_prepareRelatedNodes($nodes);
}
/**
* Takes a list of nodes and filters them so that only viewable nodes are listed,
* then adds parameters (routePrefix, href) to each node to allow links to be build
*
* @param array $nodes
*
* @return array
*/
protected function _prepareRelatedNodes(array $nodes)
{
$nodeModel = $this->_getNodeModel();
$nodeTypes = $nodeModel->getAllNodeTypes();
$nodeTypeIds = $nodeModel->getUniqueNodeTypeIdsFromNodeList($nodes);
$nodeHandlers = $nodeModel->getNodeHandlersForNodeTypes($nodeTypeIds);
$nodePermissions = $nodeModel->getNodePermissionsForPermissionCombination();
$nodes = $nodeModel->getViewableNodesFromNodeList($nodes, $nodeHandlers, $nodePermissions);
foreach ($nodes AS $nodeId => $node)
{
$routePrefix = $nodeTypes[$node['node_type_id']]['public_route_prefix'];
$nodes[$nodeId]['routePrefix'] = $routePrefix;
$nodes[$nodeId]['href'] = XenForo_Link::buildPublicLink($routePrefix, $node);
}
return $nodes;
}
/**
* Saves a page, wrapping the whole operation up in a transaction
*
* @param array $page
* @param string $template
* @param integer $nodeId
* @param integer $templateId
*
* @return integer $nodeId
*/
public function savePage(array $page, $template, $nodeId = 0, $templateId = 0)
{
$db = $this->_getDb();
XenForo_Db::beginTransaction($db);
// save page
$pageWriter = XenForo_DataWriter::create('XenForo_DataWriter_Page');
if ($nodeId)
{
$pageWriter->setExistingData($nodeId);
}
$pageWriter->bulkSet($page);
$pageWriter->save();
$page = $pageWriter->getMergedData();
// save template
$templateWriter = XenForo_DataWriter::create('XenForo_DataWriter_Template');
if ($templateId)
{
$templateWriter->setExistingData($templateId);
}
$templateWriter->set('title', $this->getTemplateTitle($page));
$templateWriter->set('template', $template);
$templateWriter->set('style_id', 0);
$templateWriter->set('addon_id', '');
$templateWriter->save();
XenForo_Db::commit($db);
$dataHandler = XenForo_Search_DataHandler_Abstract::create('XenForo_Search_DataHandler_Page');
$indexer = new XenForo_Search_Indexer();
$page['content'] = $template;
$dataHandler->insertIntoIndex($indexer, $page);
return $pageWriter->get('node_id');
}
/**
* @return XenForo_Model_Node
*/
protected function _getNodeModel()
{
return $this->getModelFromCache('XenForo_Model_Node');
}
}