/** * @param DataSet $dataSet * * @return array */ protected function parseHeaderDataSet(DataSet $dataSet) { $result = ['version' => 0, 'released' => 0, 'type' => Type::UNKNOWN]; $properties = $dataSet->getProperties(); if ($properties !== false) { if (array_key_exists('Version', $properties) && ctype_digit($properties['Version'])) { $result['version'] = (int) $properties['Version']; } if (array_key_exists('Released', $properties)) { $result['released'] = (int) strtotime($properties['Released']); } if (array_key_exists('Type', $properties)) { switch (strtolower($properties['Type'])) { case 'full': $result['type'] = Type::FULL; break; case 'lite': $result['type'] = Type::LITE; break; case '': $result['type'] = Type::STANDARD; break; } } } return $result; }
/** * @param string $data * * @return DataSet * @throws ParserRuntimeException */ protected function getDataSetFromString(string $data) : DataSet { if (strpos($data, "\n") === false) { throw new ParserRuntimeException('The data could not be parsed (no pattern found).', 1459589758); } if (strpos($data, "\r\n") !== false) { // if the source file was created under windows, replace the line endings $data = str_replace("\r\n", "\n", $data); } // Prepare the data from the data set list($pattern, $properties) = explode("\n", $data, 2); $pattern = substr($pattern, 1, -1); $properties = @parse_ini_string($properties); if ($properties === false) { throw new ParserRuntimeException("The data could not be parsed (invalid properties for pattern '{$pattern}').", 1459589759); } $dataSet = new DataSet($pattern); $dataSet->setProperties($properties); return $dataSet; }
/** * @covers ::setProperties * @covers ::getProperties * @covers ::addProperty */ public function testProperties() { $dataSet = new DataSet('JUC (Linux; U; 2.3*) UCWEB8.4*'); $dataSet->setProperties(['A' => 'x', 'B' => 'y']); static::assertSame(['A' => 'x', 'B' => 'y'], $dataSet->getProperties()); $dataSet->addProperty('C', 'z'); static::assertSame(['A' => 'x', 'B' => 'y', 'C' => 'z'], $dataSet->getProperties()); $dataSet->setProperties(['A' => 'x', 'B' => 'y']); static::assertSame(['A' => 'x', 'B' => 'y'], $dataSet->getProperties()); }
/** * @param DataSet $dataSet * * @throws ParserRuntimeException */ protected function processBrowserData(DataSet $dataSet) { // Get properties and filter them $pattern = $dataSet->getPattern(); $propertiesOriginal = $dataSet->getProperties(); $properties = $propertiesOriginal; $propertyFilter = $this->getPropertyFilter(); foreach ($properties as $propertyName => $propertyValue) { if ($propertyFilter->isFiltered($propertyName)) { unset($properties[$propertyName]); } } $browserId = $this->getNextId('browser'); // Check for placeholders $hasBrowscapPlaceholders = strpos($pattern, '*') !== false || strpos($pattern, '?') !== false; // Parent patterns do not contain browscap placeholders, so we only need to save some of them for referencing. // (Use unmodified pattern here to find them later.) if ($hasBrowscapPlaceholders === false) { $this->addParentPattern($pattern, $browserId); } // Get parent id $parentId = $this->getParentPatternId($propertiesOriginal); // Get property ids (and generate new entries for new properties) $propertyIds = $this->getIdsForProperties($properties); // Filter the keywords from the pattern (all strings containing of the characters a-z, // with at least 4 characters) and count them to check for the most important keywords // later. if ($hasBrowscapPlaceholders === true) { $this->extractKeywordsFromPattern($pattern); } // Save browser entry $this->statements['browser']->execute(['id' => $browserId, 'parent' => $parentId, 'pattern' => $pattern]); // Optimization: Do not save patterns that are used as parents, assuming that every 'real' pattern // contains a browscap placeholder. // // We use the GLOB function in Sqlite, but this is case-sensitive. So we lower-case the pattern here // (and later, when searching for it). if ($hasBrowscapPlaceholders === true) { $this->statements['search']->execute(['id' => $browserId, 'length' => strlen(str_replace('*', '', $pattern)), 'pattern' => strtolower($pattern)]); } // Save all properties for the current pattern foreach ($propertyIds as $keyId => $valueId) { $this->statements['property']->execute(['id' => $browserId, 'key' => $keyId, 'value' => $valueId]); } }