/**
  * Gets the browscap data of the used source type
  *
  * @return string
  */
 public function getBrowscapSource()
 {
     $type = Browscap::getParser()->getSourceType();
     $url = str_replace('%t', urlencode($type), $this->getBrowscapSourceUrl());
     return $this->getRemoteData($url);
 }
예제 #2
0
 /**
  * Gets the cache prefix, dependent of the used browscap dataset type.
  *
  * @return string
  */
 protected static function getCachePrefix()
 {
     switch (Browscap::getDatasetType()) {
         case Browscap::DATASET_TYPE_SMALL:
             return 'smallbrowscap';
         case Browscap::DATASET_TYPE_LARGE:
             return 'largebrowscap';
         default:
             return 'browscap';
     }
 }
예제 #3
0
 /**
  * Checks if the source needs to be updated and processes the update
  *
  * @param boolean $forceUpdate
  * @throws \RuntimeException
  */
 public function update($forceUpdate = false)
 {
     // get updater
     $updater = Browscap::getUpdater();
     // check if an updater has been set - if not, nothing will be updated
     if ($updater !== null && $updater instanceof Updater\None === false) {
         // initialize variables
         $prefix = static::getCachePrefix();
         /** @var Cache\File $cache */
         $cache = static::getCache();
         $path = $cache->getFileName("{$prefix}.ini", true);
         $readable = is_readable($path);
         $local_ts = 0;
         // do we have to check for a new update?
         if ($forceUpdate) {
             $update = true;
         } else {
             if ($readable) {
                 $local_ts = filemtime($path);
                 $update = time() - $local_ts >= $updater->getInterval();
             } else {
                 $local_ts = 0;
                 $update = true;
             }
         }
         if ($update) {
             // check version/timestamp, to se if we need to do an update
             $do_update = false;
             if ($local_ts === 0) {
                 $do_update = true;
             } else {
                 $source_version = $updater->getBrowscapVersionNumber();
                 if ($source_version !== null && $source_version > $this->getVersion()) {
                     $do_update = true;
                 } else {
                     $source_ts = $updater->getBrowscapVersion();
                     if ($source_ts > $local_ts) {
                         $do_update = true;
                     }
                 }
             }
             if ($do_update) {
                 // touch the file first so that the update is not triggered for some seconds,
                 // to avoid that the update is triggered by multiple users at the same time
                 if ($readable) {
                     $update_lock_time = 300;
                     touch($path, time() - $updater->getInterval() + $update_lock_time);
                 }
                 // get content
                 try {
                     $source_content = $updater->getBrowscapSource();
                     $source_exception = null;
                 } catch (\Exception $e) {
                     $source_content = null;
                     $source_exception = $e;
                 }
                 if (!empty($source_content)) {
                     // update internal version cache first,
                     // to get the correct version for the next cache file
                     if (isset($source_version)) {
                         static::$version = (int) $source_version;
                     } else {
                         $key = $this->pregQuote(self::BROWSCAP_VERSION_KEY);
                         if (preg_match("/\\.*[" . $key . "\\][^[]*Version=(\\d+)\\D.*/", $source_content, $matches)) {
                             if (isset($matches[1])) {
                                 static::$version = (int) $matches[1];
                             }
                         } else {
                             // ignore the error if...
                             // - we have old source data we can work with
                             // - and the data are loaded from a remote source
                             if ($readable && $updater instanceof Updater\AbstractUpdaterRemote) {
                                 touch($path);
                             } else {
                                 throw new \RuntimeException("Problem parsing the INI file.");
                             }
                         }
                     }
                     // create cache file for the new version
                     static::getCache()->set("{$prefix}.ini", $source_content, true);
                     unset($source_content);
                     // update cached version
                     static::getCache()->set("{$prefix}.version", static::$version, false);
                     // reset cached ini data
                     $this->resetCachedData();
                 } else {
                     // ignore the error if...
                     // - we have old source data we can work with
                     // - and the data are loaded from a remote source
                     if ($readable && $updater instanceof Updater\AbstractUpdaterRemote) {
                         touch($path);
                     } else {
                         throw new \RuntimeException("Error loading browscap source.", 0, $source_exception);
                     }
                 }
             } else {
                 if ($readable) {
                     touch($path);
                 }
             }
         }
     } elseif ($forceUpdate === true) {
         throw new \RuntimeException("Required updater missing for forced update.");
     }
 }
예제 #4
0
 /**
  * Gets the main/version cache directory
  *
  * @param boolean $with_version
  * @param bool $create_dir
  * @return string
  */
 public static function getCacheDirectory($with_version = false, $create_dir = false)
 {
     // get sub directory name, depending on the data set type
     // (one sub directory for each data set type and version)
     switch (Browscap::getDatasetType()) {
         case Browscap::DATASET_TYPE_SMALL:
             $subDirName = 'smallbrowscap';
             break;
         case Browscap::DATASET_TYPE_LARGE:
             $subDirName = 'largebrowscap';
             break;
         default:
             $subDirName = 'browscap';
     }
     if (static::$cache_dir === null) {
         static::setCacheDirectory(sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'browscap');
     }
     $path = static::$cache_dir;
     if ($with_version === true) {
         $path .= DIRECTORY_SEPARATOR . $subDirName;
         $path .= '_v' . Browscap::getParser()->getVersion();
         $path .= '_' . Browscap::VERSION;
     }
     if ($create_dir === true && !file_exists($path)) {
         mkdir($path, 0777, true);
     }
     return $path;
 }
예제 #5
0
 /**
  * @expectedException \Crossjoin\Browscap\Exception\ParserRuntimeException
  *
  * @covers ::update
  *
  * @throws InvalidArgumentException
  * @throws ParserConfigurationException
  * @throws ParserRuntimeException
  * @throws SourceUnavailableException
  */
 public function testUpdateLoop()
 {
     $reader = $this->getMockBuilder('\\Crossjoin\\Browscap\\Parser\\Sqlite\\Reader')->disableOriginalConstructor()->setMethods(['isUpdateRequired'])->getMock();
     $reader->expects(static::any())->method('isUpdateRequired')->willReturn(true);
     $parser = $this->getMockBuilder('\\Crossjoin\\Browscap\\Parser\\Sqlite\\Parser')->disableOriginalConstructor()->setMethods(['getReader'])->getMock();
     $parser->expects(static::any())->method('getReader')->willReturn($reader);
     $iniFile = dirname(__DIR__) . DIRECTORY_SEPARATOR . 'resources' . DIRECTORY_SEPARATOR . 'source' . DIRECTORY_SEPARATOR . 'lite_php_browscap.ini';
     $source = new File($iniFile);
     /** @var \Crossjoin\Browscap\Parser\Sqlite\Parser $parser */
     $parser->setSource($source);
     $browscap = new Browscap();
     $browscap->setParser($parser);
     $browscap->update(true);
 }
예제 #6
0
 /**
  * @param InputInterface $input
  * @param OutputInterface $output
  *
  * @return int|null|void
  * @throws ParserConfigurationException
  * @throws ParserRuntimeException
  * @throws SourceConditionNotSatisfiedException
  * @throws SourceUnavailableException
  * @throws UnexpectedValueException
  */
 protected function execute(InputInterface $input, OutputInterface $output)
 {
     $browscap = new Browscap();
     // Set source
     $source = null;
     if ($input->getOption('ini-php')) {
         $source = new PhpSetting();
     } elseif ($input->getOption('ini-load')) {
         $type = Type::STANDARD;
         switch ($input->getOption('ini-load')) {
             case 'lite':
                 $type = Type::LITE;
                 break;
             case 'full':
                 $type = Type::FULL;
                 break;
         }
         $source = new BrowscapOrg($type);
     } elseif ($input->getOption('ini-file')) {
         $file = (string) $input->getOption('ini-file');
         $source = new File($file);
     }
     if ($source !== null) {
         $browscap->getParser()->setSource($source);
     }
     // Set filter
     $filter = null;
     if ($input->getOption('filter-allowed')) {
         $properties = (array) $input->getOption('filter-allowed');
         $filter = new Allowed($properties);
     } elseif ($input->getOption('filter-disallowed')) {
         $properties = (array) $input->getOption('filter-disallowed');
         $filter = new Disallowed($properties);
     }
     if ($filter !== null) {
         $browscap->getParser()->setPropertyFilter($filter);
     }
     // Set data directory
     if ($input->getOption('dir')) {
         /** @var Parser $parser */
         $parser = $browscap->getParser();
         $parser->setDataDirectory((string) $input->getOption('dir'));
     }
     // Force an update?
     $force = false;
     if ($input->getOption('force')) {
         $force = true;
     }
     // Process update
     $output->writeln('Processing update...');
     $updated = $browscap->update($force);
     // Output result
     $version = $browscap->getParser()->getReader()->getVersion();
     $type = $browscap->getParser()->getReader()->getType();
     $name = Type::getName($type);
     if ($updated === true) {
         $output->writeln(sprintf('Browscap data successfully updated. New version: %s (%s)', $version, $name));
     } else {
         $output->writeln(sprintf('Nothing to update. Current version: %s (%s)', $version, $name));
     }
 }