Skip to content

Commit

Permalink
v1.0.1
Browse files Browse the repository at this point in the history
  • Loading branch information
xinningsu committed Jul 31, 2019
1 parent 6e010a4 commit c5b9954
Show file tree
Hide file tree
Showing 21 changed files with 1,830 additions and 1,076 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
[![MIT licensed](https://img.shields.io/badge/license-MIT-blue.svg)](./LICENSE)
[![Build Status](https://api.travis-ci.org/xinningsu/html-query.svg?branch=master)](https://travis-ci.org/xinningsu/html-query)
[![Coverage Status](https://coveralls.io/repos/github/xinningsu/html-query/badge.svg?branch=master)](https://coveralls.io/github/xinningsu/html-query)
[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/xinningsu/html-query/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/xinningsu/html-query)
[![Code Intelligence Status](https://scrutinizer-ci.com/g/xinningsu/html-query/badges/code-intelligence.svg?b=master)](https://scrutinizer-ci.com/g/xinningsu/html-query)

A jQuery-like html processor written in PHP

Expand Down
8 changes: 4 additions & 4 deletions src/HQ.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ class HQ
*
* @param string $html
*
* @return HtmlQuery
* @return HtmlDocument
*/
public static function html(string $html)
{
Expand All @@ -28,7 +28,7 @@ public static function html(string $html)
*
* @param string $file
*
* @return HtmlQuery
* @return HtmlDocument
*/
public static function htmlFile(string $file)
{
Expand All @@ -40,7 +40,7 @@ public static function htmlFile(string $file)
*
* @param string|null $html
*
* @return HtmlQuery
* @return HtmlDocument
*/
public static function instance(?string $html = null)
{
Expand All @@ -50,6 +50,6 @@ public static function instance(?string $html = null)
$doc->loadHTML($html, LIBXML_HTML_NODEFDTD | LIBXML_HTML_NOIMPLIED);
}

return new HtmlQuery($doc, $doc);
return new HtmlDocument($doc);
}
}
70 changes: 70 additions & 0 deletions src/Helper.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace Sulao\HtmlQuery;

use DOMDocument, DOMNode, DOMNodeList, DOMXPath;
use Symfony\Component\CssSelector\CssSelectorConverter;
use Traversable;

Expand Down Expand Up @@ -83,6 +84,26 @@ public static function strictArrayDiff(array $arr1, array $arr2): array
return array_values($arr);
}

/**
* Case insensitive search
*
* @param string $needle
* @param string[] $haystack
*
* @return array
*/
public static function caseInsensitiveSearch(
string $needle,
array $haystack
): array {
$needle = strtolower($needle);
$match = array_filter($haystack, function ($value) use ($needle) {
return $needle === strtolower($value);
});

return array_values($match);
}

/**
* Split the class attr value to a class array
*
Expand Down Expand Up @@ -176,4 +197,53 @@ public static function isIdSelector(

return false;
}

/**
* Query xpath to an array of DOMNode
*
* @param string $xpath
* @param DOMDocument $doc
* @param DOMNode|null $node
*
* @return DOMNode[]
*/
public static function xpathQuery(
string $xpath,
DOMDocument $doc,
?DOMNode $node = null
): array {
$docXpath = new DOMXpath($doc);
$nodeList = $docXpath->query($xpath, $node);

if (!($nodeList instanceof DOMNodeList)) {
return [];
}

return iterator_to_array($nodeList);
}

/**
* Get the node with the relationship of current node.
*
* @param DOMNode $node
* @param string $relation
*
* @return DOMNode|null
*/
public static function getRelationNode(DOMNode $node, string $relation)
{
/** @var DOMNode $node */
while (($node = $node->$relation)
&& $node instanceof DOMNode
&& $node->nodeType !== XML_DOCUMENT_NODE
) {
if ($node->nodeType !== XML_ELEMENT_NODE) {
continue;
}

return $node;
}

return null;
}
}
115 changes: 115 additions & 0 deletions src/HtmlDocument.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
<?php

namespace Sulao\HtmlQuery;

use DOMDocument, DOMNode;

/**
* Class HtmlDocument
*
* @package Sulao\HtmlQuery
*/
class HtmlDocument
{
/**
* @var DOMDocument
*/
protected $doc;

/**
* HtmlDocument constructor.
*
* @param DOMDocument $doc
*/
public function __construct(DOMDocument $doc)
{
$this->doc = $doc;
}

/**
* Get DOMDocument
*
* @return DOMDocument
*/
public function getDoc(): DOMDocument
{
return $this->doc;
}

/**
* Get the outer HTML content.
*
* @return string|null
*/
public function outerHtml()
{
return $this->doc->saveHTML();
}

/**
* Make the static object can be called as a function.
*
* @param string $selector
*
* @return HtmlQuery
*/
public function __invoke(string $selector)
{
return $this->query($selector);
}

/**
* If the parameter is raw html, then create document fragment for it,
* If the parameter is a css selector, get the descendants
* filtered by a css selector.
*
* @param string $selector css selector or raw html
*
* @return HtmlQuery
*/
public function query(string $selector)
{
if (Helper::isRawHtml($selector)) {
$frag = $this->doc->createDocumentFragment();
$frag->appendXML($selector);

return $this->resolve($frag);
}

return $this->find($selector);
}

/**
* Get the descendants of document, filtered by a selector.
*
* @param string $selector
*
* @return HtmlQuery
*/
public function find(string $selector)
{
$nodes = Helper::xpathQuery(
Helper::toXpath($selector),
$this->doc,
$this->doc
);

if (Helper::isIdSelector($selector)) {
$nodes = $nodes ? $nodes[0] : [];
}

return $this->resolve($nodes);
}

/**
* Resolve nodes to HtmlQuery instance.
*
* @param DOMNode|DOMNode[] $nodes
*
* @return HtmlQuery
*/
protected function resolve($nodes)
{
return new HtmlQuery($this->doc, $nodes);
}
}

0 comments on commit c5b9954

Please sign in to comment.