Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Доработка билдера

Парсер
  • Loading branch information...
commit 7771a48ddf91f458138b5ec7f39e58d1eddb1dd5 1 parent 49ca078
ErgallM authored
View
44 armor/index.php
@@ -80,6 +80,50 @@
<div id="load-more" class="button">Load More</div>
</div>
</div>
+
+<div id="compare" class="compare">
+ <div class="block">
+ <h3 class="q4">
+ Орб Рудры
+ <span><i>+1</i> <button class="up"></button><button class="down"></button></span>
+ </h3>
+ <div class="type"><span>Тип</span>Орбы</div>
+ <div>[Обмен невозможен], [Невозможно положить на склад аккаунта], [Невозможно положить на склад легиона]</div>
+ <div>Можно использовать с 55-го уровня.</div>
+ </div>
+
+ <div class="block">
+ <div class="title">Медленное оружие, кол-во ударов: 1 (Стихия огня)</div>
+ <div class="skills"><span>Атака</span> 270 - 330</div>
+ <div class="skills"><span>Скор. атаки</span> 2.2</div>
+ <div class="skills"><span>Сила магии</span> 860</div>
+ <div class="skills"><span>Точн. магии</span> 391</div>
+ <div class="clear"></div>
+ </div>
+
+ <div class="block">
+ <div class="skills"><span>Макс. HP</span> 509</div>
+ <div class="skills"><span>Сила магии</span> 85</div>
+ <div class="skills"><span>М. крит.</span> 20</div>
+ <div class="skills"><span>Скор. магии</span> 20%</div>
+ <div class="skills"><span>Макс. MP</span>898</div>
+ <div class="clear"></div>
+ </div>
+
+ <div class="block">
+ <div class="title">Можно усилить магическими камнями 60-го уровня и ниже.</div>
+ <div class="manastone"></div>
+ <div class="manastone"></div>
+ <div class="manastone"></div>
+ <div class="manastone"></div>
+ <div class="manastone"></div>
+ <div class="clear"></div>
+ </div>
+
+ <div class="block">
+ Можно вставить божественный камень.
+ </div>
+</div>
<script language="javascript">
window.addEvent('domready', function() {
window.s = new SearchItems({
View
3  armor/item.php
@@ -2,7 +2,7 @@
class Model_Item extends Zend_Db_Table
{
protected $_name = 'items';
- protected $_cols = array('id', 'name', 'lvl', 'type', 'slot', 'q', 'skills', 'manastoneLvl', 'manastoneCount', 'godstone', 'price', 'icon', 'image');
+ protected $_cols = array('id', 'name', 'lvl', 'type', 'slot', 'q', 'skills', 'manastoneLvl', 'manastoneCount', 'godstone', 'price', 'icon', 'image', 'links');
public function addItem($data)
{
@@ -19,6 +19,7 @@ public function addItem($data)
'price' => $this->filter($data['price']),
'icon' => $this->filter($data['icon']),
'image' => $this->filter($data['image']),
+ 'links' => $this->filter($data['links'])
);
$data['skills'] = serialize($data['skills']);
View
169 armor/parser.php
@@ -0,0 +1,169 @@
+<?php
+set_include_path(get_include_path() . PATH_SEPARATOR . dirname(__DIR__) . '/library');
+
+require_once 'ZF.php';
+require_once 'Cli.php';
+require_once 'Dom/Query.php';
+
+Zend_Db_Table::setDefaultAdapter(new Zend_Db_Adapter_Pdo_Mysql(array(
+ 'host' => 'localhost',
+ 'username' => 'root',
+ 'password' => '25459198',
+ 'charset' => 'UTF8',
+ 'dbname' => 'aion_library'
+)));
+
+class Model_Noparserdata extends Zend_Db_Table
+{
+ protected $_name = 'noparserdata';
+ protected $_cols = array('id', 'ai', 'en', 'en_compare', 'en_js', 'ru', 'ru_compare', 'ru_js');
+
+ /** @var string */
+ protected $_folder = '/home/eaglemoor/AionParser/db';
+
+ protected $_selectors = array(
+ 'ai' => '.hbody>table',
+ 'en' => 'table.aion_tooltip_container',
+ 'en_2' => '.map-box-content-wrapper',
+ 'en_image' => '.infobox-table .map_tooltip_border img',
+ 'en_compare' => '*',
+ 'en_icon' => '/res/icons/40/{name}.png'
+ );
+
+ public function parserAI($id)
+ {
+ $file = @file_get_contents($this->_folder . "/ai/$id.html");
+ if (empty($file)) return '';
+
+ $q = new Zend_Dom_Query($file);
+ $data = $q->query($this->_selectors['ai']);
+ if ($data->count()) {
+ $dom = new DOMDocument();
+ $dom->appendChild($dom->importNode($data->current(), true));
+ return $dom->saveHTML();
+ } else {
+ return '';
+ }
+ }
+
+ public function parserItem($id, $lang = 'en')
+ {
+ $file = @file_get_contents($this->_folder . "/$lang/$id.html");
+ if (empty($file)) return '';
+
+ $q = new Zend_Dom_Query($file);
+ $data = $q->query($this->_selectors['en']);
+
+ $dom = new DOMDocument();
+
+ if ($data->count()) {
+ $dom->appendChild($dom->importNode($data->current(), true));
+ } else {
+ return '';
+ }
+
+ $data = $q->query($this->_selectors['en_2'], true);
+ if ($data->count()) $dom->appendChild($dom->importNode($data->current(), true));
+
+ $data = $q->query($this->_selectors['en_image'], true);
+ if ($data->count()) $dom->appendChild($dom->importNode($data->current(), true));
+
+ $data = $q->query('img');
+ foreach ($data as $image) {
+ /** @var \DOMElement $image */
+ if (0 === strpos($image->getAttribute('src'), '/res/icons/40/')) {
+ $dom->appendChild($dom->importNode($image, true));
+ break;
+ }
+ }
+
+ return $dom->saveHTML();
+ }
+
+ public function parserCompare($id, $lang = 'en')
+ {
+ $data = @file_get_contents($this->_folder . "/$lang/compare/$id.txt");
+ return (string) $data;
+ }
+
+ public function parserJs($id, $lang = 'en')
+ {
+ $data = @file_get_contents($this->_folder . "/$lang/js/$id.js");
+ $data = str_replace('aionInjector.addTooltip(', '', $data);
+ $data = str_replace('});', '}', $data);
+ return (string) $data;
+ }
+
+ public function noparserdataToDb($id = null)
+ {
+ if (null !== $id) {
+ $saveData = array(
+ 'id' => $id,
+ 'ai' => $this->parserAI($id),
+ 'en' => $this->parserItem($id),
+ 'en_compare' => $this->parserCompare($id),
+ 'en_js' => $this->parserJs($id),
+ 'ru' => $this->parserItem($id, 'ru'),
+ 'ru_compare' => $this->parserCompare($id, 'ru'),
+ 'ru_js' => $this->parserJs($id, 'ru')
+ );
+
+ $this->createRow($saveData)->save();
+ return true;
+ }
+
+ $idArray = array();
+
+ if ($handle = opendir($this->_folder . '/ai')) {
+ echo "Дескриптор каталога: $handle\n";
+
+ while (false !== ($file = readdir($handle))) {
+ if ('.' != $file && '..' != $file) {
+ $id = (int) str_replace('.html', '', $file);
+ if (!$id) continue;
+ $idArray[$id] = $id;
+ }
+ }
+
+ closedir($handle);
+ }
+
+ echo "Обнаружено " . sizeof($idArray) . " элементов.\nНачинаю парсинг...\n";
+ $i = 0;
+ foreach ($idArray as $id) {
+ $i++;
+ $saveData = array(
+ 'id' => $id,
+ 'ai' => $this->parserAI($id),
+ 'en' => $this->parserItem($id),
+ 'en_compare' => $this->parserCompare($id),
+ 'en_js' => $this->parserJs($id),
+ 'ru' => $this->parserItem($id, 'ru'),
+ 'ru_compare' => $this->parserCompare($id, 'ru'),
+ 'ru_js' => $this->parserJs($id, 'ru')
+ );
+
+ try {
+ $this->createRow($saveData)->save();
+ } catch (\Exception $e) {
+ if (false === strpos($e->getMessage(), 'Duplicate entry')) echo 'ERROR #' . $e->getCode() . ' ' . $e->getMessage() . PHP_EOL;
+ }
+
+ echo $id . ' - ' . sizeof($idArray) . ' / ' . (sizeof($idArray) - $i) . PHP_EOL;
+ }
+ echo "PARSER END";
+ }
+}
+
+class Model_Parser
+{
+ /** @var Zend_Db_Table */
+ protected $_db = null;
+
+ /** @var string */
+ protected $_folder = '/home/eaglemoor/AionParser/db';
+}
+
+$options = Cli::getParams(array('id' => null), $argc, $argv);
+$parser = new Model_Noparserdata();
+$parser->noparserdataToDb($options['id']);
View
53 css/armor.css
@@ -16,6 +16,19 @@
#searchItems {position: absolute; margin-top: -430px; width: 500px; left: -200px;}
#posts { height:300px; overflow-y: auto; }
+#posts div {
+ height: 40px;
+ line-height: 40px;
+ border: 1px solid gray;
+ background: #14222A;
+ padding-left: 50px;
+ cursor: pointer;
+ font-size: 1.2em;
+}
+#posts div img {
+ float: left;
+ margin: 0px 5px;
+}
#addItem {margin: 0px 20px;}
#addItem > form > div {margin-bottom: 1em; padding-bottom: 1em; border-bottom: 1px solid #f5f5f5; width: 600px;}
@@ -57,3 +70,43 @@
.q2 {color: #4CCFFF !important;}
.q3 {color: #FFC103 !important;}
.q4 {color: #FF8033 !important;}
+
+.compare h3 {height: 40px; line-height: 40px; font-size: 1.286em;}
+.compare h3 button {border: none; cursor: pointer; height: 16px; width: 16px;}
+.compare h3 button.up {background: url('/images/up.png') center center no-repeat;}
+.compare h3 button.down {background: url('/images/down.png') center center no-repeat;}
+.compare h3 span {margin-left: 20px;}
+.compare h3 span i {display: inline-block; width: 25px; text-align: right;}
+
+
+.compare {
+ background: url('http://ru.aiondatabase.com/res/icons/40/icon_item_orb_e01.png') 5px 5px no-repeat;
+ width: 500px;
+ position: absolute;
+ top: 100px;
+ left: 50%;
+ z-index: 100;
+ margin-left: -250px;
+ border: 1px solid #666;
+ padding: 5px;
+ padding-left: 50px;
+ padding-right: 30px;
+}
+.compare .block {
+ border-bottom: 1px solid #666;
+ padding-bottom: 1em;
+ margin-bottom: 1em;
+}
+.compare .block:last-child {
+ border-bottom: none;
+ padding-bottom: 0px;
+}
+.compare .block .title {margin-bottom: 1em;}
+.compare .block .skills {width: 230px; padding-right: 20px; text-align: right; float: left;}
+.compare .block .skills span {float: left;}
+
+.compare .block .manastone {width: 230px; height: 40px; float: left; cursor: pointer; background: url('/images/manastone/hp-white.png') top left no-repeat; margin-bottom: 5px; margin-right: 20px;}
+.compare .block .manastone.white {background-image: url('/images/manastone/hp-white.png');}
+.compare .block .manastone.green {background-image: url('/images/manastone/hp-green.png');}
+.compare .block .type {text-align: right;}
+.compare .block .type span {float: left;}
View
BIN  images/ajax-loader.gif
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN  images/closeButtons.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN  images/down.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN  images/manastone/hp-green.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN  images/manastone/hp-white.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN  images/manastonesocket.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN  images/up.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
81 js/armor.js
@@ -21,11 +21,85 @@ var Item = new Class({
godstone: false,
price: {},
icon: '',
- image: ''
+ image: '',
+
+ /** Точка */
+ point: 0
},
+ childItem: null,
+
initialize: function(options) {
this.setOptions(options);
+ },
+
+ /**
+ * @return Element
+ */
+ createCompareDialog: function() {
+ var item = this.options;
+ var compare = new Element('div#compare-' + item.id + '.compare');
+
+ /* Start block Name */
+ var blockName = new Element('div.block');
+ var title = new Element('h3.q' + item.q, {html: item.name});
+ var titleSpan = new Element('span');
+ var titleSpanI = new Element('i', {html: item.point}).inject(titleSpan);
+ var titleSpanPointUp = new Element('button.up', {
+ click: function () {
+ console.log(item.point);
+ }
+ }).inject(titleSpan);
+ var titleSpanPointDown = new Element('button.down', {
+ click: function() {
+ console.log(item.point);
+ }
+ }).inject(titleSpan);
+ titleSpan.inject(title);
+
+ title.inject(blockName);
+
+ new Elements({
+ 'div.type': {html: '<span>Тип: </span>' + item.type},
+ 'div': {html: 'Можно использовать с ' + item.lvl + '-го уровня.'}
+ }).inject(blockName);
+
+ blockName.inject(compare);
+ /* End block Name */
+
+
+ /* start Skills Block */
+ Object.each(item.skills, function(skills, skillType) {
+ var blockSkills = new Element('div.block', {html: 'Type=' + skillType});
+
+ Object.each(skills, function(skill) {
+ new Element('div.skills', {html: '<span>' + skill.name + '</span> ' + skill.value}).inject(blockSkills);
+ });
+
+ new Element('div.clear').inject(blockSkills);
+ blockSkills.inject(compare);
+ });
+ /* end Skills Block */
+
+ /* start Manastone Block */
+ if (item.manastoneCount) {
+ var blockManastone = new Element('div.block');
+ new Element('div.title', {html: 'Можно усилить магическими камнями ' + item.manastoneLvl + '-го уровня и ниже.'}).inject(blockManastone);
+ for (var i = 0; i < item.manastoneCount; i++) {
+ new Element('div.manastone').inject(blockManastone);
+ }
+ new Element('div.clear').inject(blockManastone);
+ blockManastone.inject(compare);
+ }
+ /* end Manastone Block */
+
+ /* start Godstone */
+ if (item.godstone) {
+ new Element('div.block', {html: 'Можно вставить божественный камень.'}).inject(compare);
+ }
+ /* end Godstone */
+
+ return compare;
}
})
@@ -118,9 +192,10 @@ var SearchItems = new Class({
var that = this;
Object.each(postsJSON, function(post,i) {
var item = new Item(post);
- console.log(item);
+
new Element('div', {
- html: '<i>' + i + '</i><br>' + post,
+ html: '<img src="' + item.options.icon + '"> ' + item.options.name,
+ class: 'q' + item.options.q,
events: {
click: function() {
console.log(i, post);
View
19 library/Cli.php
@@ -0,0 +1,19 @@
+<?php
+class Cli
+{
+ public static function getParams(array $options, $argc, $argv)
+ {
+ if ($argc > 1) {
+ foreach ($argv as $com) {
+ if (0 === strpos($com, '-')) {
+ $varName = substr($com, 1, strpos($com, '=') - 1);
+ $varValue = substr($com, strpos($com, '=') + 1);
+
+ if (array_key_exists($varName, $options)) $options[$varName] = $varValue;
+ }
+ }
+ }
+
+ return $options;
+ }
+}
View
35 library/Dom/Exception.php
@@ -0,0 +1,35 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Dom
+ * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id: Exception.php 16541 2009-07-07 06:59:03Z bkarwin $
+ */
+
+/** Zend_Exception */
+//require_once 'Zend/Exception.php';
+
+/**
+ * Zend_Dom Exceptions
+ *
+ * @category Zend
+ * @package Zend_Dom
+ * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Dom_Exception extends Exception
+{
+}
View
223 library/Dom/Query.php
@@ -0,0 +1,223 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Dom
+ * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id: Query.php 17293 2009-07-30 02:34:37Z yoshida@zend.co.jp $
+ */
+
+/**
+ * @see Zend_Dom_Query_Css2Xpath
+ */
+require_once 'Query/Css2Xpath.php';
+
+/**
+ * @see Zend_Dom_Query_Result
+ */
+require_once 'Query/Result.php';
+
+/**
+ * Query DOM structures based on CSS selectors and/or XPath
+ *
+ * @package Zend_Dom
+ * @subpackage Query
+ * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Dom_Query
+{
+ /**#@+
+ * @const string Document types
+ */
+ const DOC_XML = 'docXml';
+ const DOC_HTML = 'docHtml';
+ const DOC_XHTML = 'docXhtml';
+ /**#@-*/
+
+ /**
+ * @var string
+ */
+ protected $_document;
+
+ /**
+ * Document type
+ * @var string
+ */
+ protected $_docType;
+
+ /**
+ * Constructor
+ *
+ * @param null|string $document
+ * @return void
+ */
+ public function __construct($document = null)
+ {
+ $this->setDocument($document);
+ }
+
+ /**
+ * Set document to query
+ *
+ * @param string $document
+ * @return Zend_Dom_Query
+ */
+ public function setDocument($document)
+ {
+ if (0 === strlen($document)) {
+ return $this;
+ }
+ if ('<?xml' == substr(trim($document), 0, 5)) {
+ return $this->setDocumentXml($document);
+ }
+ if (strstr($document, 'DTD XHTML')) {
+ return $this->setDocumentXhtml($document);
+ }
+ return $this->setDocumentHtml($document);
+ }
+
+ /**
+ * Register HTML document
+ *
+ * @param string $document
+ * @return Zend_Dom_Query
+ */
+ public function setDocumentHtml($document)
+ {
+ $this->_document = (string) $document;
+ $this->_docType = self::DOC_HTML;
+ return $this;
+ }
+
+ /**
+ * Register XHTML document
+ *
+ * @param string $document
+ * @return Zend_Dom_Query
+ */
+ public function setDocumentXhtml($document)
+ {
+ $this->_document = (string) $document;
+ $this->_docType = self::DOC_XHTML;
+ return $this;
+ }
+
+ /**
+ * Register XML document
+ *
+ * @param string $document
+ * @return Zend_Dom_Query
+ */
+ public function setDocumentXml($document)
+ {
+ $this->_document = (string) $document;
+ $this->_docType = self::DOC_XML;
+ return $this;
+ }
+
+ /**
+ * Retrieve current document
+ *
+ * @return string
+ */
+ public function getDocument()
+ {
+ return $this->_document;
+ }
+
+ /**
+ * Get document type
+ *
+ * @return string
+ */
+ public function getDocumentType()
+ {
+ return $this->_docType;
+ }
+
+ /**
+ * Perform a CSS selector query
+ *
+ * @param string $query
+ * @return Zend_Dom_Query_Result
+ */
+ public function query($query)
+ {
+ $xpathQuery = Zend_Dom_Query_Css2Xpath::transform($query);
+ return $this->queryXpath($xpathQuery, $query);
+ }
+
+ /**
+ * Perform an XPath query
+ *
+ * @param string|array $xpathQuery
+ * @param string $query CSS selector query
+ * @return Zend_Dom_Query_Result
+ */
+ public function queryXpath($xpathQuery, $query = null)
+ {
+ if (null === ($document = $this->getDocument())) {
+ require_once 'Exception.php';
+ throw new Zend_Dom_Exception('Cannot query; no document registered');
+ }
+
+ $domDoc = new DOMDocument;
+ $type = $this->getDocumentType();
+ switch ($type) {
+ case self::DOC_XML:
+ $success = @$domDoc->loadXML($document);
+ break;
+ case self::DOC_HTML:
+ case self::DOC_XHTML:
+ default:
+ $success = @$domDoc->loadHTML($document);
+ break;
+ }
+
+ if (!$success) {
+ require_once 'Exception.php';
+ throw new Zend_Dom_Exception(sprintf('Error parsing document (type == %s)', $type));
+ }
+
+ $nodeList = $this->_getNodeList($domDoc, $xpathQuery);
+ return new Zend_Dom_Query_Result($query, $xpathQuery, $domDoc, $nodeList);
+ }
+
+ /**
+ * Prepare node list
+ *
+ * @param DOMDocument $document
+ * @param string|array $xpathQuery
+ * @return array
+ */
+ protected function _getNodeList($document, $xpathQuery)
+ {
+ $xpath = new DOMXPath($document);
+ $xpathQuery = (string) $xpathQuery;
+ if (preg_match_all('|\[contains\((@[a-z0-9_-]+),\s?\' |i', $xpathQuery, $matches)) {
+ foreach ($matches[1] as $attribute) {
+ $queryString = '//*[' . $attribute . ']';
+ $attributeName = substr($attribute, 1);
+ $nodes = $xpath->query($queryString);
+ foreach ($nodes as $node) {
+ $attr = $node->attributes->getNamedItem($attributeName);
+ $attr->value = ' ' . $attr->value . ' ';
+ }
+ }
+ }
+ return $xpath->query($xpathQuery);
+ }
+}
View
141 library/Dom/Query/Css2Xpath.php
@@ -0,0 +1,141 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Dom
+ * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+/**
+ * Transform CSS selectors to XPath
+ *
+ * @package Zend_Dom
+ * @subpackage Query
+ * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id: Css2Xpath.php 17293 2009-07-30 02:34:37Z yoshida@zend.co.jp $
+ */
+class Zend_Dom_Query_Css2Xpath
+{
+ /**
+ * Transform CSS expression to XPath
+ *
+ * @param string $path
+ * @return string|array
+ */
+ public static function transform($path)
+ {
+ $path = (string) $path;
+ if (strstr($path, ',')) {
+ $paths = explode(',', $path);
+ $expressions = array();
+ foreach ($paths as $path) {
+ $xpath = self::transform(trim($path));
+ if (is_string($xpath)) {
+ $expressions[] = $xpath;
+ } elseif (is_array($xpath)) {
+ $expressions = array_merge($expressions, $xpath);
+ }
+ }
+ return $expressions;
+ }
+
+ $paths = array('//');
+ $segments = preg_split('/\s+/', $path);
+ foreach ($segments as $key => $segment) {
+ $pathSegment = self::_tokenize($segment);
+ if (0 == $key) {
+ if (0 === strpos($pathSegment, '[contains(@class')) {
+ $paths[0] .= '*' . $pathSegment;
+ } else {
+ $paths[0] .= $pathSegment;
+ }
+ continue;
+ }
+ if (0 === strpos($pathSegment, '[contains(@class')) {
+ foreach ($paths as $key => $xpath) {
+ $paths[$key] .= '//*' . $pathSegment;
+ $paths[] = $xpath . $pathSegment;
+ }
+ } else {
+ foreach ($paths as $key => $xpath) {
+ $paths[$key] .= '//' . $pathSegment;
+ }
+ }
+ }
+
+ if (1 == count($paths)) {
+ return $paths[0];
+ }
+ return implode(' | ', $paths);
+ }
+
+ /**
+ * Tokenize CSS expressions to XPath
+ *
+ * @param string $expression
+ * @return string
+ */
+ protected static function _tokenize($expression)
+ {
+ // Child selectors
+ $expression = str_replace('>', '/', $expression);
+
+ // IDs
+ $expression = preg_replace('|#([a-z][a-z0-9_-]*)|i', '[@id=\'$1\']', $expression);
+ $expression = preg_replace('|(?<![a-z0-9_-])(\[@id=)|i', '*$1', $expression);
+
+ // arbitrary attribute strict equality
+ if (preg_match('|([a-z]+)\[([a-z0-9_-]+)=[\'"]([^\'"]+)[\'"]\]|i', $expression)) {
+ $expression = preg_replace_callback(
+ '|([a-z]+)\[([a-z0-9_-]+)=[\'"]([^\'"]+)[\'"]\]|i',
+ create_function(
+ '$matches',
+ 'return $matches[1] . "[@" . strtolower($matches[2]) . "=\'" . $matches[3] . "\']";'
+ ),
+ $expression
+ );
+ }
+
+ // arbitrary attribute contains full word
+ if (preg_match('|([a-z]+)\[([a-z0-9_-]+)~=[\'"]([^\'"]+)[\'"]\]|i', $expression)) {
+ $expression = preg_replace_callback(
+ '|([a-z]+)\[([a-z0-9_-]+)~=[\'"]([^\'"]+)[\'"]\]|i',
+ create_function(
+ '$matches',
+ 'return $matches[1] . "[contains(@" . strtolower($matches[2]) . ", \' $matches[3] \')]";'
+ ),
+ $expression
+ );
+ }
+
+ // arbitrary attribute contains specified content
+ if (preg_match('|([a-z]+)\[([a-z0-9_-]+)\*=[\'"]([^\'"]+)[\'"]\]|i', $expression)) {
+ $expression = preg_replace_callback(
+ '|([a-z]+)\[([a-z0-9_-]+)\*=[\'"]([^\'"]+)[\'"]\]|i',
+ create_function(
+ '$matches',
+ 'return $matches[1] . "[contains(@" . strtolower($matches[2]) . ", \'" . $matches[3] . "\')]";'
+ ),
+ $expression
+ );
+ }
+
+ // Classes
+ $expression = preg_replace('|\.([a-z][a-z0-9_-]*)|i', "[contains(@class, ' \$1 ')]", $expression);
+
+ return $expression;
+ }
+}
View
183 library/Dom/Query/Result.php
@@ -0,0 +1,183 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Dom
+ * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+/**
+ * Results for DOM XPath query
+ *
+ * @package Zend_Dom
+ * @subpackage Query
+ * @uses Iterator
+ * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id: Result.php 16541 2009-07-07 06:59:03Z bkarwin $
+ */
+class Zend_Dom_Query_Result implements Iterator,Countable
+{
+ /**
+ * Number of results
+ * @var int
+ */
+ protected $_count;
+
+ /**
+ * CSS Selector query
+ * @var string
+ */
+ protected $_cssQuery;
+
+ /**
+ * @var DOMDocument
+ */
+ protected $_document;
+
+ /**
+ * @var DOMNodeList
+ */
+ protected $_nodeList;
+
+ /**
+ * Current iterator position
+ * @var int
+ */
+ protected $_position = 0;
+
+ /**
+ * @var DOMXPath
+ */
+ protected $_xpath;
+
+ /**
+ * XPath query
+ * @var string
+ */
+ protected $_xpathQuery;
+
+ /**
+ * Constructor
+ *
+ * @param string $cssQuery
+ * @param string|array $xpathQuery
+ * @param DOMDocument $document
+ * @param DOMNodeList $nodeList
+ * @return void
+ */
+ public function __construct($cssQuery, $xpathQuery, DOMDocument $document, DOMNodeList $nodeList)
+ {
+ $this->_cssQuery = $cssQuery;
+ $this->_xpathQuery = $xpathQuery;
+ $this->_document = $document;
+ $this->_nodeList = $nodeList;
+ }
+
+ /**
+ * Retrieve CSS Query
+ *
+ * @return string
+ */
+ public function getCssQuery()
+ {
+ return $this->_cssQuery;
+ }
+
+ /**
+ * Retrieve XPath query
+ *
+ * @return string
+ */
+ public function getXpathQuery()
+ {
+ return $this->_xpathQuery;
+ }
+
+ /**
+ * Retrieve DOMDocument
+ *
+ * @return DOMDocument
+ */
+ public function getDocument()
+ {
+ return $this->_document;
+ }
+
+ /**
+ * Iterator: rewind to first element
+ *
+ * @return void
+ */
+ public function rewind()
+ {
+ $this->_position = 0;
+ return $this->_nodeList->item(0);
+ }
+
+ /**
+ * Iterator: is current position valid?
+ *
+ * @return bool
+ */
+ public function valid()
+ {
+ if (in_array($this->_position, range(0, $this->_nodeList->length - 1)) && $this->_nodeList->length > 0) {
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Iterator: return current element
+ *
+ * @return DOMElement
+ */
+ public function current()
+ {
+ return $this->_nodeList->item($this->_position);
+ }
+
+ /**
+ * Iterator: return key of current element
+ *
+ * @return int
+ */
+ public function key()
+ {
+ return $this->_position;
+ }
+
+ /**
+ * Iterator: move to next element
+ *
+ * @return void
+ */
+ public function next()
+ {
+ ++$this->_position;
+ return $this->_nodeList->item($this->_position);
+ }
+
+ /**
+ * Countable: get count
+ *
+ * @return int
+ */
+ public function count()
+ {
+ return $this->_nodeList->length;
+ }
+}
Please sign in to comment.
Something went wrong with that request. Please try again.