/**
  * Given a `$url` and `$timeout`, this function will use the `Gateway`
  * class to determine that it is a valid URL and returns successfully
  * before the `$timeout`. If it does not, an error message will be
  * returned, otherwise true.
  *
  * @since Symphony 2.3
  * @param string $url
  * @param integer $timeout
  *  If not provided, this will default to 6 seconds
  * @param string $error
  *  If this function returns false, this variable will be populated with the
  *  error message.
  * @return array|boolean
  *  Returns an array with the 'data' if it is a valid URL, otherwise a string
  *  containing an error message.
  */
 public static function __isValidURL($url, $timeout = 6, &$error)
 {
     if (!filter_var($url, FILTER_VALIDATE_URL)) {
         $error = __('Invalid URL');
         return false;
     }
     // Check that URL was provided
     $gateway = new Gateway();
     $gateway->init($url);
     $gateway->setopt('TIMEOUT', $timeout);
     $data = $gateway->exec();
     $info = $gateway->getInfoLast();
     // 28 is CURLE_OPERATION_TIMEDOUT
     if ($info['curl_error'] == 28) {
         $error = __('Request timed out. %d second limit reached.', array($timeout));
         return false;
     } elseif ($data === false || $info['http_code'] != 200) {
         $error = __('Failed to load URL, status code %d was returned.', array($info['http_code']));
         return false;
     }
     return array('data' => $data);
 }
 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;
 }
Ejemplo n.º 3
0
$cachedData = $cache->check($cache_id);
$writeToCache = false;
$valid = true;
$creation = DateTimeObj::get('c');
$timeout = isset($this->dsParamTIMEOUT) ? (int) max(1, $this->dsParamTIMEOUT) : 6;
if (!is_array($cachedData) || empty($cachedData) || time() - $cachedData['creation'] > $this->dsParamCACHE * 60) {
    if (Mutex::acquire($cache_id, $timeout, TMP)) {
        $start = precision_timer();
        $ch = new Gateway();
        $ch->init();
        $ch->setopt('URL', $this->dsParamURL);
        $ch->setopt('TIMEOUT', $timeout);
        $xml = $ch->exec();
        $writeToCache = true;
        $end = precision_timer('stop', $start);
        $info = $ch->getInfoLast();
        Mutex::release($cache_id, TMP);
        $xml = trim($xml);
        // 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;
            if (is_array($cachedData) && !empty($cachedData)) {
                $xml = trim($cachedData['data']);
                $valid = false;
                $creation = DateTimeObj::get('c', $cachedData['creation']);
            } else {
                $result->setAttribute('valid', 'false');
                if ($end > $timeout) {
                    $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'])));
 /**
  * Get all HTTP response headers and info as an array of arrays.
  *
  * @since 1.17
  *
  * @param string $url
  * @return array
  *  Contains the headers and the infos
  */
 public static function getHttpHead($url)
 {
     // Check if we have a cached result
     if (isset(self::$_result[$url])) {
         return self::$_result[$url];
     }
     // create the Gateway object
     $gateway = new Gateway();
     // set our url
     $gateway->init($url);
     // set some options
     $gateway->setopt(CURLOPT_URL, $url);
     $gateway->setopt(CURLOPT_RETURNTRANSFER, true);
     $gateway->setopt(CURLOPT_HEADER, true);
     $gateway->setopt(CURLOPT_NOBODY, true);
     $gateway->setopt(CURLOPT_FOLLOWLOCATION, true);
     $gateway->setopt(CURLOPT_MAXREDIRS, Image::CURL_MAXREDIRS);
     // get the raw head response, ignore errors
     $head = @$gateway->exec();
     // Get all info
     $result = array('headers' => array(), 'info' => $gateway->getInfoLast());
     // Clean up
     $gateway->flush();
     if ($head !== false) {
         $result['headers'] = self::parseHttpHeaderFields($head);
     }
     // Save for subsequent requests
     self::$_result[$url] = $result;
     return $result;
 }
Ejemplo n.º 5
0
 public function render(Register $ParameterOutput)
 {
     $result = null;
     $doc = new XMLDocument();
     if (isset($this->parameters()->url)) {
         $this->parameters()->url = self::replaceParametersInString($this->parameters()->url, $ParameterOutput);
     }
     if (isset($this->parameters()->xpath)) {
         $this->parameters()->xpath = self::replaceParametersInString($this->parameters()->xpath, $ParameterOutput);
     }
     $cache_id = md5($this->parameters()->url . serialize($this->parameters()->namespaces) . $this->parameters()->xpath);
     $cache = Cache::instance();
     $cachedData = $cache->read($cache_id);
     $writeToCache = false;
     $force_empty_result = false;
     $valid = true;
     $result = NULL;
     $creation = DateTimeObj::get('c');
     if (isset($this->parameters()->timeout)) {
         $timeout = (int) max(1, $this->parameters()->timeout);
     }
     if (!is_array($cachedData) || empty($cachedData) || time() - $cachedData['creation'] > $this->parameters()->{'cache-timeout'} * 60) {
         if (Mutex::acquire($cache_id, $timeout, TMP)) {
             $start = precision_timer();
             $ch = new Gateway();
             $ch->init();
             $ch->setopt('URL', $this->parameters()->url);
             $ch->setopt('TIMEOUT', $this->parameters()->timeout);
             $xml = $ch->exec();
             $writeToCache = true;
             $end = precision_timer('STOP', $start);
             $info = $ch->getInfoLast();
             Mutex::release($cache_id, TMP);
             $xml = trim($xml);
             if ((int) $info['http_code'] != 200 || !preg_match('/(xml|plain|text)/i', $info['content_type'])) {
                 $writeToCache = false;
                 if (is_array($cachedData) && !empty($cachedData)) {
                     $xml = trim($cachedData['data']);
                     $valid = false;
                     $creation = DateTimeObj::get('c', $cachedData['creation']);
                 } else {
                     $result = $doc->createElement($this->parameters()->{'root-element'});
                     $result->setAttribute('valid', 'false');
                     if ($end > $timeout) {
                         $result->appendChild($doc->createElement('error', sprintf('Request timed out. %d second limit reached.', $timeout)));
                     } else {
                         $result->appendChild($doc->createElement('error', sprintf('Status code %d was returned. Content-type: %s', $info['http_code'], $info['content_type'])));
                     }
                     return $result;
                 }
             } elseif (strlen($xml) > 0 && !General::validateXML($xml, $errors)) {
                 $writeToCache = false;
                 if (is_array($cachedData) && !empty($cachedData)) {
                     $xml = trim($cachedData['data']);
                     $valid = false;
                     $creation = DateTimeObj::get('c', $cachedData['creation']);
                 } else {
                     $result = $doc->createElement($this->parameters()->{'root-element'}, $doc->createElement('error', __('XML returned is invalid.')), array('valid' => 'false'));
                     return $result;
                 }
             } elseif (strlen($xml) == 0) {
                 $force_empty_result = true;
             }
         } elseif (is_array($cachedData) && !empty($cachedData)) {
             $xml = trim($cachedData['data']);
             $valid = false;
             $creation = DateTimeObj::get('c', $cachedData['creation']);
             if (empty($xml)) {
                 $force_empty_result = true;
             }
         } else {
             $force_empty_result = true;
         }
     } else {
         $xml = trim($cachedData['data']);
         $creation = DateTimeObj::get('c', $cachedData['creation']);
     }
     if (!$force_empty_result) {
         $result = new XMLDocument();
         $root = $result->createElement($this->parameters()->{'root-element'});
         //XPath Approach, saves Transforming the Document.
         $xDom = new XMLDocument();
         $xDom->loadXML($xml);
         if ($xDom->hasErrors()) {
             $root->setAttribute('valid', 'false');
             $root->appendChild($result->createElement('error', __('XML returned is invalid.')));
             $messages = $result->createElement('messages');
             foreach ($xDom->getErrors() as $e) {
                 if (strlen(trim($e->message)) == 0) {
                     continue;
                 }
                 $messages->appendChild($result->createElement('item', General::sanitize($e->message)));
             }
             $root->appendChild($messages);
         } else {
             if ($writeToCache) {
                 $cache->write($cache_id, $xml);
             }
             $xpath = new DOMXPath($xDom);
             ## Namespaces
             if (is_array($this->parameters()->namespaces) && !empty($this->parameters()->namespaces)) {
                 foreach ($this->parameters()->namespaces as $index => $namespace) {
                     $xpath->registerNamespace($namespace['name'], $namespace['uri']);
                 }
             }
             $xpath_list = $xpath->query($this->parameters()->xpath);
             foreach ($xpath_list as $node) {
                 if ($node instanceof XMLDocument) {
                     $root->appendChild($result->importNode($node->documentElement, true));
                 } else {
                     $root->appendChild($result->importNode($node, true));
                 }
             }
             $root->setAttribute('status', $valid === true ? 'fresh' : 'stale');
             $root->setAttribute('creation', $creation);
         }
     }
     if (!$root->hasChildNodes() || $force_empty_result) {
         $this->emptyXMLSet($root);
     }
     $result->appendChild($root);
     return $result;
 }
 public static function getVideoFeed($video_id)
 {
     // Fetch document:
     $gateway = new Gateway();
     $gateway->init();
     $gateway->setopt('URL', "http://gdata.youtube.com/feeds/api/videos/{$video_id}");
     $gateway->setopt('TIMEOUT', 10);
     $data = $gateway->exec();
     $info = $gateway->getInfoLast();
     if ($data == "Invalid id" || empty($data) || $info['http_code'] != 200) {
         return null;
     }
     return DOMDocument::loadXML($data);
 }
Ejemplo n.º 7
0
 public function validate($source = null, $remote = true)
 {
     if (!function_exists('handleXMLError')) {
         function handleXMLError($errno, $errstr, $errfile, $errline, $context)
         {
             $context['self']->_errors[] = $errstr;
         }
     }
     set_time_limit(900);
     set_error_handler('handleXMLError');
     $self = $this;
     // F*****g PHP...
     $options = $this->options();
     $passed = true;
     if ($remote) {
         if (!is_null($source)) {
             $options['source'] = $source;
         }
         // Support {$root}
         $options['source'] = str_replace('{$root}', URL, $options['source']);
         // Parse timeout, default is 60
         $timeout = isset($options['timeout']) ? (int) $options['timeout'] : 60;
         // Fetch document:
         $gateway = new Gateway();
         $gateway->init();
         $gateway->setopt('URL', $options['source']);
         $gateway->setopt('TIMEOUT', $timeout);
         $data = $gateway->exec();
         $info = $gateway->getInfoLast();
         if (empty($data) || $info['http_code'] >= 400) {
             $this->_errors[] = __('No data to import. URL returned HTTP code %d', array($info['http_code']));
             $passed = false;
         }
     } else {
         if (!is_null($source)) {
             $data = $source;
         } else {
             $this->_errors[] = __('No data to import.');
             $passed = false;
         }
     }
     if (!is_array($options['fields'])) {
         $this->_errors[] = __('No field mappings have been set for this XML Importer.');
         $passed = false;
     }
     if (!$passed) {
         return self::__ERROR_PREPARING__;
     }
     // Load document:
     $xml = new DOMDocument();
     $xml->loadXML($data);
     restore_error_handler();
     $xpath = new DOMXPath($xml);
     $passed = true;
     // Register namespaces:
     if (is_array($options['namespaces'])) {
         foreach ($options['namespaces'] as $namespace) {
             $xpath->registerNamespace($namespace['name'], $namespace['uri']);
         }
     }
     // Invalid Markup:
     if (empty($xml)) {
         $passed = false;
     } else {
         if (($entries = $xpath->query($options['included-elements'])) === false) {
             $this->_errors[] = __('Root expression <code>%s</code> is invalid.', array(General::sanitize($options['included-elements'])));
             $passed = false;
         } else {
             if (is_null($entries) or $entries->length == 0) {
                 $this->_errors[] = __('No entries to import.');
                 $passed = false;
             } else {
                 foreach ($options['fields'] as $mapping) {
                     if ($xpath->evaluate(stripslashes($mapping['xpath'])) !== false) {
                         continue;
                     }
                     $field = FieldManager::fetch($mapping['field']);
                     $this->_errors[] = __('\'%s\' expression <code>%s</code> is invalid.', array($field->get('label'), General::sanitize($mapping['xpath'])));
                     $passed = false;
                 }
             }
         }
     }
     if (!$passed) {
         return self::__ERROR_PREPARING__;
     }
     // Gather data:
     foreach ($entries as $index => $entry) {
         $this->_entries[$index] = array('element' => $entry, 'values' => array(), 'errors' => array(), 'entry' => null);
         foreach ($options['fields'] as $mapping) {
             $values = $this->getExpressionValue($xml, $entry, $xpath, $mapping['xpath'], $debug);
             if (isset($mapping['php']) && $mapping['php'] != '') {
                 $php = stripslashes($mapping['php']);
                 // static helper
                 if (preg_match('/::/', $php)) {
                     foreach ($values as $id => $value) {
                         $values[$id] = call_user_func_array($php, array($value));
                     }
                 } else {
                     foreach ($values as $id => $value) {
                         $function = preg_replace('/\\$value/', "'" . $value . "'", $php);
                         if (!preg_match('/^return/', $function)) {
                             $function = 'return ' . $function;
                         }
                         if (!preg_match('/;$/', $function)) {
                             $function .= ';';
                         }
                         $values[$id] = @eval($function);
                     }
                 }
             }
             $this->_entries[$index]['values'][$mapping['field']] = $values;
         }
     }
     // Validate:
     $passed = true;
     foreach ($this->_entries as &$current) {
         $entry = EntryManager::create();
         $entry->set('section_id', $options['section']);
         $entry->set('author_id', is_null(Symphony::Engine()->Author()) ? '1' : Symphony::Engine()->Author()->get('id'));
         $values = array();
         // Map values:
         foreach ($current['values'] as $field_id => $value) {
             $field = FieldManager::fetch($field_id);
             if (is_array($value)) {
                 if (count($value) === 1) {
                     $value = current($value);
                 }
                 if (count($value) === 0) {
                     $value = '';
                 }
             }
             // Adjust value?
             if (method_exists($field, 'prepareImportValue') && method_exists($field, 'getImportModes')) {
                 $modes = $field->getImportModes();
                 if (is_array($modes) && !empty($modes)) {
                     $mode = current($modes);
                 }
                 $value = $field->prepareImportValue($value, $mode, $entry->get('id'));
             } else {
                 $type = $field->get('type');
                 if ($type == 'author') {
                     if ($field->get('allow_multiple_selection') == 'no') {
                         if (is_array($value)) {
                             $value = array(implode('', $value));
                         }
                     }
                 } else {
                     if ($type == 'datetime') {
                         $value = $value[0];
                     } else {
                         if (is_array($value)) {
                             $value = implode('', $value);
                         }
                     }
                 }
             }
             $values[$field->get('element_name')] = $value;
         }
         // Validate:
         if (__ENTRY_FIELD_ERROR__ == $entry->checkPostData($values, $current['errors'])) {
             $passed = false;
         } else {
             if (__ENTRY_OK__ != $entry->setDataFromPost($values, $current['errors'], true, true)) {
                 $passed = false;
             }
         }
         $current['entry'] = $entry;
         $current['values'] = $values;
     }
     if (!$passed) {
         return self::__ERROR_VALIDATING__;
     }
     return self::__OK__;
 }