Esempio n. 1
0
 /**
  * Constructor for the HTMLPage. Intialises the class variables with
  * empty instances of XMLElement
  */
 public function __construct()
 {
     parent::__construct();
     $this->Html = new XMLElement('html');
     $this->Html->setIncludeHeader(false);
     $this->Head = new XMLElement('head');
     $this->Body = new XMLElement('body');
 }
Esempio n. 2
0
 /**
  * The constructor for `XMLPage`. This sets the page status to `Page::HTTP_STATUS_OK`,
  * the default content type to `text/xml` and initialises `$this->_Result`
  * with an `XMLElement`. The constructor also starts the Profiler for this
  * page template.
  *
  * @see toolkit.Profiler
  */
 public function __construct()
 {
     $this->_Result = new XMLElement('result');
     $this->_Result->setIncludeHeader(true);
     $this->setHttpStatus(self::HTTP_STATUS_OK);
     $this->addHeaderToPage('Content-Type', 'text/xml');
     Symphony::Profiler()->sample('Page template created', PROFILE_LAP);
 }
Esempio n. 3
0
 /**
  * The constructor for AJAXPage. This sets the page status to `STATUS_OK`,
  * the default content type to text/xml and initialises `$this->_Result`
  * with an XMLElement. The constructor also starts the Profiler for this
  * page template.
  *
  * @see toolkit.Profiler
  * @param Administration $parent
  *  The Administration object that this page has been created from
  *  passed by reference
  */
 public function __construct(&$parent)
 {
     $this->_Parent = $parent;
     $this->_Result = new XMLElement('result');
     $this->_Result->setIncludeHeader(true);
     $this->_status = self::STATUS_OK;
     $this->addHeaderToPage('Content-Type', 'text/xml');
     Administration::instance()->Profiler->sample('Page template created', PROFILE_LAP);
 }
 public function execute(array &$param_pool = null)
 {
     $result = new XMLElement($this->dsParamROOTELEMENT);
     $this->dsParamURL = $this->parseParamURL($this->dsParamURL);
     if (isset($this->dsParamXPATH)) {
         $this->dsParamXPATH = $this->__processParametersInString($this->dsParamXPATH, $this->_env);
     }
     $stylesheet = new XMLElement('xsl:stylesheet');
     $stylesheet->setAttributeArray(array('version' => '1.0', 'xmlns:xsl' => 'http://www.w3.org/1999/XSL/Transform'));
     $output = new XMLElement('xsl:output');
     $output->setAttributeArray(array('method' => 'xml', 'version' => '1.0', 'encoding' => 'utf-8', 'indent' => 'yes', 'omit-xml-declaration' => 'yes'));
     $stylesheet->appendChild($output);
     $template = new XMLElement('xsl:template');
     $template->setAttribute('match', '/');
     $instruction = new XMLElement('xsl:copy-of');
     // Namespaces
     if (isset($this->dsParamFILTERS) && is_array($this->dsParamFILTERS)) {
         foreach ($this->dsParamFILTERS as $name => $uri) {
             $instruction->setAttribute('xmlns' . ($name ? ":{$name}" : null), $uri);
         }
     }
     // XPath
     $instruction->setAttribute('select', $this->dsParamXPATH);
     $template->appendChild($instruction);
     $stylesheet->appendChild($template);
     $stylesheet->setIncludeHeader(true);
     $xsl = $stylesheet->generate(true);
     $cache_id = md5($this->dsParamURL . serialize($this->dsParamFILTERS) . $this->dsParamXPATH);
     $cache = new Cacheable(Symphony::Database());
     $cachedData = $cache->read($cache_id);
     $writeToCache = false;
     $valid = true;
     $creation = DateTimeObj::get('c');
     $timeout = isset($this->dsParamTIMEOUT) ? (int) max(1, $this->dsParamTIMEOUT) : 6;
     // Execute if the cache doesn't exist, or if it is old.
     if (!is_array($cachedData) || empty($cachedData) || time() - $cachedData['creation'] > $this->dsParamCACHE * 60) {
         if (Mutex::acquire($cache_id, $timeout, TMP)) {
             $ch = new Gateway();
             $ch->init($this->dsParamURL);
             $ch->setopt('TIMEOUT', $timeout);
             $ch->setopt('HTTPHEADER', array('Accept: text/xml, */*'));
             $data = $ch->exec();
             $info = $ch->getInfoLast();
             Mutex::release($cache_id, TMP);
             $data = trim($data);
             $writeToCache = true;
             // Handle any response that is not a 200, or the content type does not include XML, plain or text
             if ((int) $info['http_code'] !== 200 || !preg_match('/(xml|plain|text)/i', $info['content_type'])) {
                 $writeToCache = false;
                 $result->setAttribute('valid', 'false');
                 // 28 is CURLE_OPERATION_TIMEOUTED
                 if ($info['curl_error'] == 28) {
                     $result->appendChild(new XMLElement('error', sprintf('Request timed out. %d second limit reached.', $timeout)));
                 } else {
                     $result->appendChild(new XMLElement('error', sprintf('Status code %d was returned. Content-type: %s', $info['http_code'], $info['content_type'])));
                 }
                 return $result;
                 // Handle where there is `$data`
             } elseif (strlen($data) > 0) {
                 // If the XML doesn't validate..
                 if (!General::validateXML($data, $errors, false, new XsltProcess())) {
                     $writeToCache = false;
                 }
                 // If the `$data` is invalid, return a result explaining why
                 if ($writeToCache === false) {
                     $element = new XMLElement('errors');
                     $result->setAttribute('valid', 'false');
                     $result->appendChild(new XMLElement('error', __('Data returned is invalid.')));
                     foreach ($errors as $e) {
                         if (strlen(trim($e['message'])) == 0) {
                             continue;
                         }
                         $element->appendChild(new XMLElement('item', General::sanitize($e['message'])));
                     }
                     $result->appendChild($element);
                     return $result;
                 }
                 // If `$data` is empty, set the `force_empty_result` to true.
             } elseif (strlen($data) == 0) {
                 $this->_force_empty_result = true;
             }
             // Failed to acquire a lock
         } else {
             $result->appendChild(new XMLElement('error', __('The %s class failed to acquire a lock, check that %s exists and is writable.', array('<code>Mutex</code>', '<code>' . TMP . '</code>'))));
         }
         // The cache is good, use it!
     } else {
         $data = trim($cachedData['data']);
         $creation = DateTimeObj::get('c', $cachedData['creation']);
     }
     // If `$writeToCache` is set to false, invalidate the old cache if it existed.
     if (is_array($cachedData) && !empty($cachedData) && $writeToCache === false) {
         $data = trim($cachedData['data']);
         $valid = false;
         $creation = DateTimeObj::get('c', $cachedData['creation']);
         if (empty($data)) {
             $this->_force_empty_result = true;
         }
     }
     // If `force_empty_result` is false and `$result` is an instance of
     // XMLElement, build the `$result`.
     if (!$this->_force_empty_result && is_object($result)) {
         $proc = new XsltProcess();
         $ret = $proc->process($data, $xsl);
         if ($proc->isErrors()) {
             $result->setAttribute('valid', 'false');
             $error = new XMLElement('error', __('Transformed XML is invalid.'));
             $result->appendChild($error);
             $element = new XMLElement('errors');
             foreach ($proc->getError() as $e) {
                 if (strlen(trim($e['message'])) == 0) {
                     continue;
                 }
                 $element->appendChild(new XMLElement('item', General::sanitize($e['message'])));
             }
             $result->appendChild($element);
         } elseif (strlen(trim($ret)) == 0) {
             $this->_force_empty_result = true;
         } else {
             if ($writeToCache) {
                 $cache->write($cache_id, $data, $this->dsParamCACHE);
             }
             $result->setValue(PHP_EOL . str_repeat("\t", 2) . preg_replace('/([\\r\\n]+)/', "\$1\t", $ret));
             $result->setAttribute('status', $valid === true ? 'fresh' : 'stale');
             $result->setAttribute('creation', $creation);
         }
     }
     return $result;
 }
Esempio n. 5
0
    private function __buildPage()
    {
        $start = precision_timer();
        if (!($page = $this->resolvePage())) {
            $page = $this->_Parent->Database->fetchRow(0, "\n\t\t\t\t\t\t\t\tSELECT `tbl_pages`.* \n\t\t\t\t\t\t\t\tFROM `tbl_pages`, `tbl_pages_types` \n\t\t\t\t\t\t\t\tWHERE `tbl_pages_types`.page_id = `tbl_pages`.id \n\t\t\t\t\t\t\t\tAND tbl_pages_types.`type` = '404' \n\t\t\t\t\t\t\t\tLIMIT 1");
            if (empty($page)) {
                $this->_Parent->customError(E_USER_ERROR, __('Page Not Found'), __('The page you requested does not exist.'), false, true, 'error', array('header' => 'HTTP/1.0 404 Not Found'));
            }
            $page['filelocation'] = $this->resolvePageFileLocation($page['path'], $page['handle']);
            $page['type'] = $this->__fetchPageTypes($page['id']);
        }
        ####
        # Delegate: FrontendPageResolved
        # Description: Just after having resolved the page, but prior to any commencement of output creation
        # Global: Yes
        $this->ExtensionManager->notifyMembers('FrontendPageResolved', '/frontend/', array('page' => &$this, 'page_data' => &$page));
        $this->_pageData = $page;
        $root_page = @array_shift(explode('/', $page['path']));
        $current_path = explode(dirname($_SERVER['SCRIPT_NAME']), $_SERVER['REQUEST_URI'], 2);
        $current_path = '/' . ltrim(end($current_path), '/');
        // Get max upload size from php and symphony config then choose the smallest
        $upload_size_php = ini_size_to_bytes(ini_get('upload_max_filesize'));
        $upload_size_sym = Frontend::instance()->Configuration->get('max_upload_size', 'admin');
        $this->_param = array('today' => DateTimeObj::get('Y-m-d'), 'current-time' => DateTimeObj::get('H:i'), 'this-year' => DateTimeObj::get('Y'), 'this-month' => DateTimeObj::get('m'), 'this-day' => DateTimeObj::get('d'), 'timezone' => DateTimeObj::get('P'), 'website-name' => $this->_Parent->Configuration->get('sitename', 'general'), 'page-title' => $page['title'], 'root' => URL, 'workspace' => URL . '/workspace', 'root-page' => $root_page ? $root_page : $page['handle'], 'current-page' => $page['handle'], 'current-page-id' => $page['id'], 'current-path' => $current_path, 'parent-path' => '/' . $page['path'], 'current-url' => URL . $current_path, 'upload-limit' => min($upload_size_php, $upload_size_sym), 'symphony-build' => $this->_Parent->Configuration->get('build', 'symphony'));
        if (is_array($this->_env['url'])) {
            foreach ($this->_env['url'] as $key => $val) {
                $this->_param[$key] = $val;
            }
        }
        if (is_array($_GET) && !empty($_GET)) {
            foreach ($_GET as $key => $val) {
                if (!in_array($key, array('symphony-page', 'debug', 'profile'))) {
                    $this->_param['url-' . $key] = $val;
                }
            }
        }
        if (is_array($_COOKIE[__SYM_COOKIE_PREFIX_]) && !empty($_COOKIE[__SYM_COOKIE_PREFIX_])) {
            foreach ($_COOKIE[__SYM_COOKIE_PREFIX_] as $key => $val) {
                $this->_param['cookie-' . $key] = $val;
            }
        }
        // Flatten parameters:
        General::flattenArray($this->_param);
        ####
        # Delegate: FrontendParamsResolve
        # Description: Just after having resolved the page params, but prior to any commencement of output creation
        # Global: Yes
        $this->ExtensionManager->notifyMembers('FrontendParamsResolve', '/frontend/', array('params' => &$this->_param));
        $xml_build_start = precision_timer();
        $xml = new XMLElement('data');
        $xml->setIncludeHeader(true);
        $events = new XMLElement('events');
        $this->__processEvents($page['events'], $events);
        $xml->appendChild($events);
        $this->_events_xml = clone $events;
        $this->__processDatasources($page['data_sources'], $xml);
        $this->_Parent->Profiler->seed($xml_build_start);
        $this->_Parent->Profiler->sample('XML Built', PROFILE_LAP);
        if (is_array($this->_env['pool']) && !empty($this->_env['pool'])) {
            foreach ($this->_env['pool'] as $handle => $p) {
                if (!is_array($p)) {
                    $p = array($p);
                }
                foreach ($p as $key => $value) {
                    if (is_array($value) && !empty($value)) {
                        foreach ($value as $kk => $vv) {
                            $this->_param[$handle] .= @implode(', ', $vv) . ',';
                        }
                    } else {
                        $this->_param[$handle] = @implode(', ', $p);
                    }
                }
                $this->_param[$handle] = trim($this->_param[$handle], ',');
            }
        }
        ####
        # Delegate: FrontendParamsPostResolve
        # Description: Access to the resolved param pool, including additional parameters provided by Data Source outputs
        # Global: Yes
        $this->ExtensionManager->notifyMembers('FrontendParamsPostResolve', '/frontend/', array('params' => $this->_param));
        ## TODO: Add delegate for adding/removing items in the params
        $xsl = '<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
	<xsl:import href="./workspace/pages/' . basename($page['filelocation']) . '"/>
</xsl:stylesheet>';
        $this->_Parent->Profiler->seed();
        $this->setXML($xml->generate(true, 0));
        $this->_Parent->Profiler->sample('XML Generation', PROFILE_LAP);
        $this->setXSL($xsl, false);
        $this->setRuntimeParam($this->_param);
        $this->_Parent->Profiler->seed($start);
        $this->_Parent->Profiler->sample('Page Built', PROFILE_LAP);
    }
 public function execute(array &$param_pool = null)
 {
     $result = new XMLElement($this->dsParamROOTELEMENT);
     // When DS is called out of the Frontend context, this will enable
     // {$root} and {$workspace} parameters to be evaluated
     if (empty($this->_env)) {
         $this->_env['env']['pool'] = array('root' => URL, 'workspace' => WORKSPACE);
     }
     try {
         require_once TOOLKIT . '/class.gateway.php';
         require_once TOOLKIT . '/class.xsltprocess.php';
         require_once CORE . '/class.cacheable.php';
         $this->dsParamURL = $this->parseParamURL($this->dsParamURL);
         if (isset($this->dsParamXPATH)) {
             $this->dsParamXPATH = $this->__processParametersInString(stripslashes($this->dsParamXPATH), $this->_env);
         }
         // Builds a Default Stylesheet to transform the resulting XML with
         $stylesheet = new XMLElement('xsl:stylesheet');
         $stylesheet->setAttributeArray(array('version' => '1.0', 'xmlns:xsl' => 'http://www.w3.org/1999/XSL/Transform'));
         $output = new XMLElement('xsl:output');
         $output->setAttributeArray(array('method' => 'xml', 'version' => '1.0', 'encoding' => 'utf-8', 'indent' => 'yes', 'omit-xml-declaration' => 'yes'));
         $stylesheet->appendChild($output);
         $template = new XMLElement('xsl:template');
         $template->setAttribute('match', '/');
         $instruction = new XMLElement('xsl:copy-of');
         // Namespaces
         if (isset($this->dsParamNAMESPACES) && is_array($this->dsParamNAMESPACES)) {
             foreach ($this->dsParamNAMESPACES as $name => $uri) {
                 $instruction->setAttribute('xmlns' . ($name ? ":{$name}" : null), $uri);
             }
         }
         // XPath
         $instruction->setAttribute('select', $this->dsParamXPATH);
         $template->appendChild($instruction);
         $stylesheet->appendChild($template);
         $stylesheet->setIncludeHeader(true);
         $xsl = $stylesheet->generate(true);
         // Check for an existing Cache for this Datasource
         $cache_id = self::buildCacheID($this);
         $cache = Symphony::ExtensionManager()->getCacheProvider('remotedatasource');
         $cachedData = $cache->check($cache_id);
         $writeToCache = null;
         $isCacheValid = true;
         $creation = DateTimeObj::get('c');
         // Execute if the cache doesn't exist, or if it is old.
         if (!is_array($cachedData) || empty($cachedData) || time() - $cachedData['creation'] > $this->dsParamCACHE * 60) {
             if (Mutex::acquire($cache_id, $this->dsParamTIMEOUT, TMP)) {
                 $ch = new Gateway();
                 $ch->init($this->dsParamURL);
                 $ch->setopt('TIMEOUT', $this->dsParamTIMEOUT);
                 // Set the approtiate Accept: headers depending on the format of the URL.
                 if ($this->dsParamFORMAT == 'xml') {
                     $ch->setopt('HTTPHEADER', array('Accept: text/xml, */*'));
                 } elseif ($this->dsParamFORMAT == 'json') {
                     $ch->setopt('HTTPHEADER', array('Accept: application/json, */*'));
                 } elseif ($this->dsParamFORMAT == 'csv') {
                     $ch->setopt('HTTPHEADER', array('Accept: text/csv, */*'));
                 }
                 self::prepareGateway($ch);
                 $data = $ch->exec();
                 $info = $ch->getInfoLast();
                 Mutex::release($cache_id, TMP);
                 $data = trim($data);
                 $writeToCache = true;
                 // Handle any response that is not a 200, or the content type does not include XML, JSON, plain or text
                 if ((int) $info['http_code'] != 200 || !preg_match('/(xml|json|csv|plain|text)/i', $info['content_type'])) {
                     $writeToCache = false;
                     $result->setAttribute('valid', 'false');
                     // 28 is CURLE_OPERATION_TIMEOUTED
                     if ($info['curl_error'] == 28) {
                         $result->appendChild(new XMLElement('error', sprintf('Request timed out. %d second limit reached.', $timeout)));
                     } else {
                         $result->appendChild(new XMLElement('error', sprintf('Status code %d was returned. Content-type: %s', $info['http_code'], $info['content_type'])));
                     }
                     return $result;
                 } else {
                     if (strlen($data) > 0) {
                         // Handle where there is `$data`
                         // If it's JSON, convert it to XML
                         if ($this->dsParamFORMAT == 'json') {
                             try {
                                 require_once TOOLKIT . '/class.json.php';
                                 $data = JSON::convertToXML($data);
                             } catch (Exception $ex) {
                                 $writeToCache = false;
                                 $errors = array(array('message' => $ex->getMessage()));
                             }
                         } elseif ($this->dsParamFORMAT == 'csv') {
                             try {
                                 require_once EXTENSIONS . '/remote_datasource/lib/class.csv.php';
                                 $data = CSV::convertToXML($data);
                             } catch (Exception $ex) {
                                 $writeToCache = false;
                                 $errors = array(array('message' => $ex->getMessage()));
                             }
                         } elseif ($this->dsParamFORMAT == 'txt') {
                             $txtElement = new XMLElement('entry');
                             $txtElement->setValue(General::wrapInCDATA($data));
                             $data = $txtElement->generate();
                             $txtElement = null;
                         } else {
                             if (!General::validateXML($data, $errors, false, new XsltProcess())) {
                                 // If the XML doesn't validate..
                                 $writeToCache = false;
                             }
                         }
                         // If the `$data` is invalid, return a result explaining why
                         if ($writeToCache === false) {
                             $error = new XMLElement('errors');
                             $error->setAttribute('valid', 'false');
                             $error->appendChild(new XMLElement('error', __('Data returned is invalid.')));
                             foreach ($errors as $e) {
                                 if (strlen(trim($e['message'])) == 0) {
                                     continue;
                                 }
                                 $error->appendChild(new XMLElement('item', General::sanitize($e['message'])));
                             }
                             $result->appendChild($error);
                             return $result;
                         }
                     } elseif (strlen($data) == 0) {
                         // If `$data` is empty, set the `force_empty_result` to true.
                         $this->_force_empty_result = true;
                     }
                 }
             } else {
                 // Failed to acquire a lock
                 $result->appendChild(new XMLElement('error', __('The %s class failed to acquire a lock.', array('<code>Mutex</code>'))));
             }
         } else {
             // The cache is good, use it!
             $data = trim($cachedData['data']);
             $creation = DateTimeObj::get('c', $cachedData['creation']);
         }
         // Visit the data
         $this->exposeData($data);
         // If `$writeToCache` is set to false, invalidate the old cache if it existed.
         if (is_array($cachedData) && !empty($cachedData) && $writeToCache === false) {
             $data = trim($cachedData['data']);
             $isCacheValid = false;
             $creation = DateTimeObj::get('c', $cachedData['creation']);
             if (empty($data)) {
                 $this->_force_empty_result = true;
             }
         }
         // If `force_empty_result` is false and `$result` is an instance of
         // XMLElement, build the `$result`.
         if (!$this->_force_empty_result && is_object($result)) {
             $proc = new XsltProcess();
             $ret = $proc->process($data, $xsl);
             if ($proc->isErrors()) {
                 $result->setAttribute('valid', 'false');
                 $error = new XMLElement('error', __('Transformed XML is invalid.'));
                 $result->appendChild($error);
                 $errors = new XMLElement('errors');
                 foreach ($proc->getError() as $e) {
                     if (strlen(trim($e['message'])) == 0) {
                         continue;
                     }
                     $errors->appendChild(new XMLElement('item', General::sanitize($e['message'])));
                 }
                 $result->appendChild($errors);
                 $result->appendChild(new XMLElement('raw-data', General::wrapInCDATA($data)));
             } elseif (strlen(trim($ret)) == 0) {
                 $this->_force_empty_result = true;
             } else {
                 if ($this->dsParamCACHE > 0 && $writeToCache) {
                     $cache->write($cache_id, $data, $this->dsParamCACHE);
                 }
                 $result->setValue(PHP_EOL . str_repeat("\t", 2) . preg_replace('/([\\r\\n]+)/', "\$1\t", $ret));
                 $result->setAttribute('status', $isCacheValid === true ? 'fresh' : 'stale');
                 $result->setAttribute('cache-id', $cache_id);
                 $result->setAttribute('creation', $creation);
             }
         }
     } catch (Exception $e) {
         $result->appendChild(new XMLElement('error', $e->getMessage()));
     }
     if ($this->_force_empty_result) {
         $result = $this->emptyXMLSet();
     }
     $result->setAttribute('url', General::sanitize($this->dsParamURL));
     return $result;
 }
$stylesheet->setAttributeArray(array('version' => '1.0', 'xmlns:xsl' => 'http://www.w3.org/1999/XSL/Transform'));
$output = new XMLElement('xsl:output');
$output->setAttributeArray(array('method' => 'xml', 'version' => '1.0', 'encoding' => 'utf-8', 'indent' => 'yes', 'omit-xml-declaration' => 'yes'));
$stylesheet->appendChild($output);
$template = new XMLElement('xsl:template');
$template->setAttribute('match', '/');
$instruction = new XMLElement('xsl:copy-of');
## Namespaces
foreach ($this->dsParamFILTERS as $name => $uri) {
    $instruction->setAttribute('xmlns' . ($name ? ":{$name}" : NULL), $uri);
}
## XPath
$instruction->setAttribute('select', $this->dsParamXPATH);
$template->appendChild($instruction);
$stylesheet->appendChild($template);
$stylesheet->setIncludeHeader(true);
$xsl = $stylesheet->generate(true);
$proc =& new XsltProcess();
$cache_id = md5($this->dsParamURL . serialize($this->dsParamFILTERS) . $this->dsParamXPATH);
$cache = new Cacheable($this->_Parent->Database);
$cachedData = $cache->check($cache_id);
$writeToCache = false;
$valid = true;
$result = NULL;
$creation = DateTimeObj::get('c');
if (!$cachedData || time() - $cachedData['creation'] > $this->dsParamCACHE * 60) {
    if (Mutex::acquire($cache_id, 6, TMP)) {
        $ch = new Gateway();
        $ch->init();
        $ch->setopt('URL', $this->dsParamURL);
        $ch->setopt('TIMEOUT', 6);
    /**
     * This function sets the page's parameters, processes the Datasources and
     * Events and sets the `$xml` and `$xsl` variables. This functions resolves the `$page`
     * by calling the `resolvePage()` function. If a page is not found, it attempts
     * to locate the Symphony 404 page set in the backend otherwise it throws
     * the default Symphony 404 page. If the page is found, the page's XSL utility
     * is found, and the system parameters are set, including any URL parameters,
     * params from the Symphony cookies. Events and Datasources are executed and
     * any parameters  generated by them are appended to the existing parameters
     * before setting the Page's XML and XSL variables are set to the be the
     * generated XML (from the Datasources and Events) and the XSLT (from the
     * file attached to this Page)
     *
     * @uses FrontendPageResolved
     * @uses FrontendParamsResolve
     * @uses FrontendParamsPostResolve
     * @see resolvePage()
     */
    private function __buildPage()
    {
        $start = precision_timer();
        if (!($page = $this->resolvePage())) {
            throw new FrontendPageNotFoundException();
        }
        /**
         * Just after having resolved the page, but prior to any commencement of output creation
         * @delegate FrontendPageResolved
         * @param string $context
         * '/frontend/'
         * @param FrontendPage $page
         *  An instance of this class, passed by reference
         * @param array $page_data
         *  An associative array of page data, which is a combination from `tbl_pages` and
         *  the path of the page on the filesystem. Passed by reference
         */
        Symphony::ExtensionManager()->notifyMembers('FrontendPageResolved', '/frontend/', array('page' => &$this, 'page_data' => &$page));
        $this->_pageData = $page;
        $path = explode('/', $page['path']);
        $root_page = is_array($path) ? array_shift($path) : $path;
        $current_path = explode(dirname($_SERVER['SCRIPT_NAME']), $_SERVER['REQUEST_URI'], 2);
        $current_path = '/' . ltrim(end($current_path), '/');
        $split_path = explode('?', $current_path, 3);
        $current_path = rtrim(current($split_path), '/');
        $querystring = '?' . next($split_path);
        // Get max upload size from php and symphony config then choose the smallest
        $upload_size_php = ini_size_to_bytes(ini_get('upload_max_filesize'));
        $upload_size_sym = Symphony::Configuration()->get('max_upload_size', 'admin');
        $this->_param = array('today' => DateTimeObj::get('Y-m-d'), 'current-time' => DateTimeObj::get('H:i'), 'this-year' => DateTimeObj::get('Y'), 'this-month' => DateTimeObj::get('m'), 'this-day' => DateTimeObj::get('d'), 'timezone' => DateTimeObj::get('P'), 'website-name' => Symphony::Configuration()->get('sitename', 'general'), 'page-title' => $page['title'], 'root' => URL, 'workspace' => URL . '/workspace', 'root-page' => $root_page ? $root_page : $page['handle'], 'current-page' => $page['handle'], 'current-page-id' => $page['id'], 'current-path' => $current_path, 'parent-path' => '/' . $page['path'], 'current-query-string' => XMLElement::stripInvalidXMLCharacters(utf8_encode(urldecode($querystring))), 'current-url' => URL . $current_path, 'upload-limit' => min($upload_size_php, $upload_size_sym), 'symphony-version' => Symphony::Configuration()->get('version', 'symphony'));
        if (is_array($this->_env['url'])) {
            foreach ($this->_env['url'] as $key => $val) {
                $this->_param[$key] = $val;
            }
        }
        if (is_array($_GET) && !empty($_GET)) {
            foreach ($_GET as $key => $val) {
                if (in_array($key, array('symphony-page', 'debug', 'profile'))) {
                    continue;
                }
                // If the browser sends encoded entities for &, ie. a=1&amp;b=2
                // this causes the $_GET to output they key as amp;b, which results in
                // $url-amp;b. This pattern will remove amp; allow the correct param
                // to be used, $url-b
                $key = preg_replace('/(^amp;|\\/)/', null, $key);
                // If the key gets replaced out then it will break the XML so prevent
                // the parameter being set.
                if (!General::createHandle($key)) {
                    continue;
                }
                $this->_param['url-' . $key] = XMLElement::stripInvalidXMLCharacters(utf8_encode(urldecode($val)));
            }
        }
        if (is_array($_COOKIE[__SYM_COOKIE_PREFIX_]) && !empty($_COOKIE[__SYM_COOKIE_PREFIX_])) {
            foreach ($_COOKIE[__SYM_COOKIE_PREFIX_] as $key => $val) {
                $this->_param['cookie-' . $key] = $val;
            }
        }
        // Flatten parameters:
        General::flattenArray($this->_param);
        /**
         * Just after having resolved the page params, but prior to any commencement of output creation
         * @delegate FrontendParamsResolve
         * @param string $context
         * '/frontend/'
         * @param array $params
         *  An associative array of this page's parameters
         */
        Symphony::ExtensionManager()->notifyMembers('FrontendParamsResolve', '/frontend/', array('params' => &$this->_param));
        $xml_build_start = precision_timer();
        $xml = new XMLElement('data');
        $xml->setIncludeHeader(true);
        $events = new XMLElement('events');
        $this->processEvents($page['events'], $events);
        $xml->appendChild($events);
        $this->_events_xml = clone $events;
        $this->processDatasources($page['data_sources'], $xml);
        Symphony::Profiler()->seed($xml_build_start);
        Symphony::Profiler()->sample('XML Built', PROFILE_LAP);
        if (is_array($this->_env['pool']) && !empty($this->_env['pool'])) {
            foreach ($this->_env['pool'] as $handle => $p) {
                if (!is_array($p)) {
                    $p = array($p);
                }
                foreach ($p as $key => $value) {
                    if (is_array($value) && !empty($value)) {
                        foreach ($value as $kk => $vv) {
                            $this->_param[$handle] .= @implode(', ', $vv) . ',';
                        }
                    } else {
                        $this->_param[$handle] = @implode(', ', $p);
                    }
                }
                $this->_param[$handle] = trim($this->_param[$handle], ',');
            }
        }
        /**
         * Access to the resolved param pool, including additional parameters provided by Data Source outputs
         * @delegate FrontendParamsPostResolve
         * @param string $context
         * '/frontend/'
         * @param array $params
         *  An associative array of this page's parameters
         */
        Symphony::ExtensionManager()->notifyMembers('FrontendParamsPostResolve', '/frontend/', array('params' => &$this->_param));
        $params = new XMLElement('params');
        foreach ($this->_param as $key => $value) {
            // To support multiple parameters using the 'datasource.field'
            // we will pop off the field handle prior to sanitizing the
            // key. This is because of a limitation where General::createHandle
            // will strip '.' as it's technically punctuation.
            if (strpos($key, '.') !== false) {
                $parts = explode('.', $key);
                $field_handle = '.' . array_pop($parts);
                $key = implode('', $parts);
            } else {
                $field_handle = '';
            }
            $key = Lang::createHandle($key) . $field_handle;
            $param = new XMLElement($key);
            // DS output params get flattened to a string, so get the original pre-flattened array
            if (isset($this->_env['pool'][$key])) {
                $value = $this->_env['pool'][$key];
            }
            if (is_array($value) && !(count($value) == 1 && empty($value[0]))) {
                foreach ($value as $key => $value) {
                    $item = new XMLElement('item', General::sanitize($value));
                    $item->setAttribute('handle', Lang::createHandle($value));
                    $param->appendChild($item);
                }
            } else {
                if (is_array($value)) {
                    $param->setValue(General::sanitize($value[0]));
                } else {
                    $param->setValue(General::sanitize($value));
                }
            }
            $params->appendChild($param);
        }
        $xml->prependChild($params);
        Symphony::Profiler()->seed();
        $this->setXML($xml->generate(true, 0));
        Symphony::Profiler()->sample('XML Generation', PROFILE_LAP);
        $xsl = '<?xml version="1.0" encoding="UTF-8"?>
			<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
				<xsl:import href="./workspace/pages/' . basename($page['filelocation']) . '"/>
			</xsl:stylesheet>';
        $this->setXSL($xsl, false);
        $this->setRuntimeParam($this->_param);
        Symphony::Profiler()->seed($start);
        Symphony::Profiler()->sample('Page Built', PROFILE_LAP);
    }
            $description = '<p><strong>Author:</strong> ' . $fragment['data']['author-name'][0] . '<br />' . CRLF . '<strong>Email:</strong> ' . $fragment['data']['author-email'][0] . '<br />' . CRLF . (isset($fragment['data']['author-url']) ? '<strong>Website:</strong> ' . $fragment['data']['author-url'][0] . '<br />' . CRLF : '') . '<strong>Entry:</strong> <a href="' . $fragment['data']['referrer'][0] . '">' . $fragment['data']['referrer'][0] . '</a></p>' . CRLF . CRLF . '<p>' . $fragment['data']['body'][0] . '</p>';
            break;
        case 'version':
            $fragment = flattenFragment($fragment, $type);
            ## Skip this one if there is no update
            if (!isset($fragment['data']['update'])) {
                continue 2;
            }
            $title = '[Update] ' . $fragment['data']['announcement'][0];
            $link = $guid = 'http://accounts.symphony21.com';
            $pubdate = date("D, d M Y H:i:s \\G\\M\\T", $obDate->get(false, false, strtotime($fragment['data']['releasedate'][0])));
            $description = '<p><em>You get this update from <a href="' . $link . '">your account</a> page.</em></p>' . $fragment['data']['change-log'][0];
            break;
    }
    $item->addChild(new XMLElement('title', General::sanitize($title)));
    if ($description) {
        $item->addChild(new XMLElement('description', General::sanitize($description)));
    }
    $item->addChild(new XMLElement('link', General::sanitize($link)));
    $item->addChild(new XMLElement('pubDate', $pubdate));
    $item->addChild(new XMLElement('guid', General::sanitize($guid)));
    $channel->addChild($item);
}
$rss->addChild($channel);
##RSS XML is returned, make sure the browser knows it
header("Content-Type: text/xml");
$rss->setIncludeHeader(true);
print $rss->generate(true);
## Important. Need this otherwise rest of Symphony admin
## laods.
exit;
Esempio n. 10
0
 function buildXML($page_handle = NULL, $utilities = NULL, $indent = false, $caching = true)
 {
     $events = new XMLElement("events");
     $xml = new XMLElement("data");
     $xml->setIncludeHeader(true);
     $page_handle = $page_handle ? $page_handle : $this->_page;
     $sql = "SELECT t1.*,\n\t\t\t\t\t\t   t2.events as `master_events`,\n\t\t\t\t\t\t   t2.data_sources as `master_data_sources`\n\n\t\t\t\t\tFROM `tbl_pages` AS `t1`\n\t\t\t\t\tLEFT JOIN `tbl_masters` AS `t2` ON t1.`master` = concat(t2.`name`, '.xsl')\n\t\t\t\t\tWHERE t1.`handle` = '" . $page_handle . "' LIMIT 1";
     if (!($page = $this->_db->fetchRow(0, $sql))) {
         $this->fatalError("Requested page '" . $page_handle . "' could not be found");
     }
     $page_data = preg_split('/,/', $page['data_sources'] . "," . $page['master_data_sources'], -1, PREG_SPLIT_NO_EMPTY);
     $page_events = preg_split('/,/', $page['events'] . "," . $page['master_events'], -1, PREG_SPLIT_NO_EMPTY);
     $page_data = General::array_remove_duplicates($page_data);
     $page_events = General::array_remove_duplicates($page_events);
     ##EVENTS
     if (is_array($page_events) && !empty($page_events)) {
         foreach ($page_events as $e) {
             $this->_EventManager->addEvent($e);
         }
     }
     $this->_EventManager->fireEvents($events, array('parent' => $this, 'env' => $this->_env));
     $this->_EventManager->flush();
     $xml->addChild($events);
     $this->_events = $events;
     ##DATASOURCES
     $dsParam = array("indent-depth" => 1, "caching" => $caching, "indent" => $indent, "preview" => $this->_preview, "allow_optimise" => $page['optimise_xml'] == "yes" ? 'on' : 'off');
     if (is_array($page_data) && !empty($page_data)) {
         foreach ($page_data as $d) {
             $this->_DatasourceManager->addDatasource($d, $dsParam);
         }
     }
     $this->_DatasourceManager->renderData($xml, array('parent' => $this, 'env' => $this->_env));
     $this->_DatasourceManager->flush();
     ##Generate the final XML
     $this->_xml_final = $xml->generate($indent, 0);
     $doctor = new XMLRepair();
     $doctor->repair($this->_xml_final);
     unset($doctor);
     $this->_xml_final = trim($this->_xml_final);
     return $this->_xml_final;
 }
     $profiler->sample("Page Initialization", PROFILE_LAP);
     ##Use preview mode
     if ($_GET['mode'] == 'preview') {
         $Site->togglePreviewMode();
     }
     #Render the page
     $output = $Site->display(array(), 'TRANSFORMED', false);
     $xml = $Site->buildXML(NULL, NULL, true, false);
     $xsl = $Site->display(array(), "XSL", false);
     #Record the render time
     $profiler->sample("Total Page Render Time");
     break;
 case "datasource":
     $DSM = new DatasourceManager(array('parent' => &$Admin));
     $obXML = new XMLElement("data");
     $obXML->setIncludeHeader(true);
     ##DATASOURCES
     $dsParam = array("indent-depth" => 2, "caching" => false, "indent" => true, "preview" => true);
     $ds =& $DSM->create($page_handle, array('parent' => $this, 'env' => array()));
     $result = $ds->preview($dsParam);
     if (@is_object($result)) {
         $xml = trim($result->generate(true, 0));
     } else {
         $xml = trim($result);
     }
     $page_name = $page_handle;
     $active = "xml";
     if ($xml == "") {
         $output = $xml = $xsl = "No Datasource by the name '{$page_handle}' was found.";
     }
     break;
Esempio n. 12
0
    /**
     *
     * Builds the content view
     */
    public function view()
    {
        // _context[0] => entry values
        // _context[1] => fieldId
        if (!is_array($this->_context) || empty($this->_context)) {
            $this->_Result->appendChild(new XMLElement('error', __('Parameters not found')));
            return;
        } else {
            if (count($this->_context) < self::NUMBER_OF_URL_PARAMETERS) {
                $this->_Result->appendChild(new XMLElement('error', __('Not enough parameters')));
                return;
            } else {
                if (count($this->_context) > self::NUMBER_OF_URL_PARAMETERS) {
                    $this->_Result->appendChild(new XMLElement('error', __('Too many parameters')));
                    return;
                }
            }
        }
        $entriesId = explode(',', MySQL::cleanValue($this->_context[0]));
        $entriesId = array_map(array('General', 'intval'), $entriesId);
        if (!is_array($entriesId) || empty($entriesId)) {
            $this->_Result->appendChild(new XMLElement('error', __('No entry no found')));
            return;
        }
        $parentFieldId = General::intval($this->_context[1]);
        if ($parentFieldId < 1) {
            $this->_Result->appendChild(new XMLElement('error', __('Parent field id not valid')));
            return;
        }
        $parentField = $this->fieldManager->fetch($parentFieldId);
        if (!$parentField || empty($parentField)) {
            $this->_Result->appendChild(new XMLElement('error', __('Parent field not found')));
            return;
        }
        if ($parentField->get('type') != 'entry_relationship') {
            $this->_Result->appendChild(new XMLElement('error', __('Parent field is `%s`, not `entry_relationship`', array($parentField->get('type')))));
            return;
        }
        $includedElements = $this->parseIncludedElements($parentField);
        $xmlParams = self::getXmlParams();
        // Get entries one by one since they may belong to
        // different sections, which prevents us from
        // passing an array of entryId.
        foreach ($entriesId as $key => $entryId) {
            $entry = $this->entryManager->fetch($entryId);
            if (empty($entry)) {
                $li = new XMLElement('li', null, array('data-entry-id' => $entryId));
                $header = new XMLElement('header', null, array('class' => 'frame-header'));
                $title = new XMLElement('h4');
                $title->appendChild(new XMLElement('strong', __('Entry %s not found', array($entryId))));
                $header->appendChild($title);
                $options = new XMLElement('div', null, array('class' => 'destructor'));
                if ($parentField->is('allow_link')) {
                    $options->appendChild(new XMLElement('a', __('Un-link'), array('class' => 'unlink', 'data-unlink' => $entryId)));
                }
                $header->appendChild($options);
                $li->appendChild($header);
                $this->_Result->appendChild($li);
            } else {
                $entry = $entry[0];
                $entryData = $entry->getData();
                $entrySection = $this->sectionManager->fetch($entry->get('section_id'));
                $entryVisibleFields = $entrySection->fetchVisibleColumns();
                $entryFields = $entrySection->fetchFields();
                $entrySectionHandle = $this->getSectionName($entry, 'handle');
                $li = new XMLElement('li', null, array('data-entry-id' => $entryId, 'data-section' => $entrySectionHandle, 'data-section-id' => $entrySection->get('id')));
                $header = new XMLElement('header', null, array('class' => 'frame-header'));
                $title = new XMLElement('h4');
                $title->appendChild(new XMLElement('strong', $this->getEntryTitle($entry, $entryVisibleFields, $entryFields)));
                $title->appendChild(new XMLElement('span', $this->getSectionName($entry)));
                $header->appendChild($title);
                $options = new XMLElement('div', null, array('class' => 'destructor'));
                if ($parentField->is('allow_edit')) {
                    $title->setAttribute('data-edit', $entryId);
                    $options->appendChild(new XMLElement('a', __('Edit'), array('class' => 'edit', 'data-edit' => $entryId)));
                }
                if ($parentField->is('allow_delete')) {
                    $options->appendChild(new XMLElement('a', __('Delete'), array('class' => 'delete', 'data-delete' => $entryId)));
                }
                if ($parentField->is('allow_link')) {
                    $options->appendChild(new XMLElement('a', __('Replace'), array('class' => 'unlink', 'data-replace' => $entryId)));
                }
                if ($parentField->is('allow_delete') || $parentField->is('allow_link')) {
                    $options->appendChild(new XMLElement('a', __('Un-link'), array('class' => 'unlink', 'data-unlink' => $entryId)));
                }
                $header->appendChild($options);
                $li->appendChild($header);
                $xslFilePath = WORKSPACE . '/er-templates/' . $entrySectionHandle . '.xsl';
                if (!empty($entryData) && !!@file_exists($xslFilePath)) {
                    $xmlData = new XMLElement('data');
                    $xmlData->setIncludeHeader(true);
                    $xml = new XMLElement('entry');
                    $xml->setAttribute('id', $entryId);
                    $xmlData->appendChild($xmlParams);
                    $xmlData->appendChild($xml);
                    foreach ($entryData as $fieldId => $data) {
                        $filteredData = array_filter($data, function ($value) {
                            return $value != null;
                        });
                        if (empty($filteredData)) {
                            continue;
                        }
                        $field = $entryFields[$fieldId];
                        $fieldName = $field->get('element_name');
                        $fieldIncludedElement = $includedElements[$entrySectionHandle];
                        if (FieldEntry_relationship::isFieldIncluded($fieldName, $fieldIncludedElement)) {
                            $fieldIncludableElements = $field->fetchIncludableElements();
                            if ($field instanceof FieldEntry_relationship) {
                                $fieldIncludableElements = null;
                            }
                            if (!empty($fieldIncludableElements) && count($fieldIncludableElements) > 1) {
                                foreach ($fieldIncludableElements as $fieldIncludableElement) {
                                    $submode = preg_replace('/^' . $fieldName . '\\s*\\:\\s*/i', '', $fieldIncludableElement, 1);
                                    $field->appendFormattedElement($xml, $data, false, $submode, $entryId);
                                }
                            } else {
                                $field->appendFormattedElement($xml, $data, false, null, $entryId);
                            }
                        }
                    }
                    $indent = false;
                    $mode = $parentField->get('mode');
                    if (isset($_REQUEST['debug'])) {
                        $mode = 'debug';
                    }
                    if ($mode == 'debug') {
                        $indent = true;
                    }
                    $xmlMode = empty($mode) ? '' : 'mode="' . $mode . '"';
                    $xmlString = $xmlData->generate($indent, 0);
                    $xsl = '<?xml version="1.0" encoding="UTF-8"?>
						<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
							<xsl:import href="' . str_replace('\\', '/', $xslFilePath) . '"/>
							<xsl:output method="xml" omit-xml-declaration="yes" encoding="UTF-8" indent="no" />
							<xsl:template match="/">
								<xsl:apply-templates select="/data" ' . $xmlMode . ' />
							</xsl:template>
							<xsl:template match="/data" ' . $xmlMode . '>
								<xsl:apply-templates select="entry" ' . $xmlMode . ' />
							</xsl:template>
							<xsl:template match="/data" mode="debug">
								<xsl:copy-of select="/" />
							</xsl:template>
						</xsl:stylesheet>';
                    $xslt = new XsltProcess();
                    $result = $xslt->process($xmlString, $xsl, $this->params);
                    if ($mode == 'debug') {
                        $result = '<pre><code>' . str_replace('<', '&lt;', str_replace('>', '&gt;', $xmlString)) . '</code></pre>';
                    }
                    if ($xslt->isErrors()) {
                        $error = $xslt->getError();
                        $result = $error[1]['message'];
                    }
                    if (!!$xslt && strlen($result) > 0) {
                        $content = new XMLElement('div', $result, array('class' => 'content'));
                        $li->appendChild($content);
                    }
                }
                $this->_Result->appendChild($li);
            }
        }
    }
Esempio n. 13
0
    $Author = new Author($Parent, $author_id);
} else {
    $xml = new XMLElement('error', 'You do not have permission to access this page');
}
if (is_object($Author)) {
    ##Run requested script, returning an error if the action was not found
    if (@is_file(AJAX . "/ajax." . $_REQUEST['action'] . ".php")) {
        $xml = new XMLElement($_REQUEST['action']);
        include_once AJAX . "/ajax." . $_REQUEST['action'] . ".php";
    } else {
        $action_parts = preg_split('/\\//', $_REQUEST['action'], -1, PREG_SPLIT_NO_EMPTY);
        $action_path = str_replace(end($action_parts) . '/', '', $_REQUEST['action']);
        $action_name = rtrim(str_replace($action_path, '', $_REQUEST['action']), '/');
        $file_path = CAMPFIRE . $action_path . "/ajax/ajax." . $action_name . ".php";
        if (@is_file($file_path)) {
            $xml = new XMLElement($action_name);
            include_once $file_path;
        } else {
            $xml = new XMLElement("error", "Ajax action '" . $_REQUEST['action'] . "' does not exist.");
        }
    }
}
#Close the database connections
@$db->close();
#Record the render time
$rendertime = precision_timer("stop", STARTTIME);
##XML is returned, make sure the browser knows it
header("Content-Type: text/xml");
$xml->setIncludeHeader(true);
print $xml->generate(true);
exit;