summaryrefslogtreecommitdiffstats
path: root/utility
diff options
context:
space:
mode:
authorBernhard Posselt <dev@bernhard-posselt.com>2014-04-08 18:50:10 +0200
committerBernhard Posselt <dev@bernhard-posselt.com>2014-04-08 18:50:10 +0200
commit31ae116fe4ab5cac3d2a85069adae2d211ecc846 (patch)
tree10c02f09fb0086b7553091fb73c299d9b294385d /utility
parent83e8691308971680977b6e29d7c1fbd790e4eb16 (diff)
migrated database, utility, bootstrap from appframework
Diffstat (limited to 'utility')
-rw-r--r--utility/faviconfetcher.php151
-rw-r--r--utility/simplepieapifactory.php56
-rw-r--r--utility/simplepiefilefactory.php35
-rw-r--r--utility/timefactory.php42
4 files changed, 249 insertions, 35 deletions
diff --git a/utility/faviconfetcher.php b/utility/faviconfetcher.php
new file mode 100644
index 000000000..d5d270a49
--- /dev/null
+++ b/utility/faviconfetcher.php
@@ -0,0 +1,151 @@
+<?php
+
+/**
+ * ownCloud - News
+ *
+ * @author Bernhard Posselt
+ * @copyright 2012 Bernhard Posselt dev@bernhard-posselt.com
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU AFFERO GENERAL PUBLIC LICENSE for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+namespace OCA\News\Utility;
+
+
+class FaviconFetcher {
+
+ private $apiFactory;
+
+
+ /**
+ * Inject a factory to build a simplepie file object. This is needed because
+ * the file object contains logic in its constructor which makes it
+ * impossible to inject and test
+ */
+ public function __construct(SimplePieAPIFactory $apiFactory) {
+ $this->apiFactory = $apiFactory;
+ }
+
+
+ /**
+ * Fetches a favicon from a given URL
+ * @param string|null $url the url where to fetch it from
+ */
+ public function fetch($url) {
+ try {
+ $url = $this->buildURL($url);
+ } catch (NoValidUrlException $e) {
+ return null;
+ }
+
+ $faviconUrl = $this->extractFromPage($url);
+
+ // check the url for a valid image
+ if($faviconUrl && $this->isImage($faviconUrl)) {
+ return $faviconUrl;
+ } elseif($url) {
+ // try /favicon.ico as fallback
+ $parts = parse_url($url);
+ $faviconUrl = $parts['scheme'] . "://" . $parts['host'] . (array_key_exists("port", $parts) ? $parts['port'] : '') . "/favicon.ico";
+
+ if($this->isImage($faviconUrl)) {
+ return $faviconUrl;
+ }
+ }
+
+ return null;
+ }
+
+
+ /**
+ * Tries to get a favicon from a page
+ * @param string $url the url to the page
+ * @return string the full url to the page
+ */
+ protected function extractFromPage($url) {
+ if(!$url) {
+ return null;
+ }
+
+ $file = $this->apiFactory->getFile($url);
+
+ if($file->body !== '') {
+ $document = new \DOMDocument();
+ @$document->loadHTML($file->body);
+
+ if($document) {
+ $xpath = new \DOMXpath($document);
+ $elements = $xpath->query("//link[contains(@rel, 'icon')]");
+
+ if ($elements->length > 0) {
+ $iconPath = $elements->item(0)->getAttribute('href');
+ $absPath = \SimplePie_Misc::absolutize_url($iconPath, $url);
+ return $absPath;
+ }
+ }
+ }
+ }
+
+
+ /**
+ * Test if the file is an image
+ * @param string $url the url to the file
+ * @return bool true if image
+ */
+ protected function isImage($url) {
+ // check for empty urls
+ if(!$url) {
+ return false;
+ }
+
+ $file = $this->apiFactory->getFile($url);
+ $sniffer = new \SimplePie_Content_Type_Sniffer($file);
+ return $sniffer->image() !== false;
+ }
+
+
+ /**
+ * Get HTTP or HTTPS addresses from an incomplete URL
+ * @param string $url the url that should be built
+ * @return string a string containing the http or https address
+ * @throws NoValidUrlException when no valid url can be returned
+ */
+ protected function buildURL($url) {
+ // trim the right / from the url
+ $url = trim($url);
+ $url = rtrim($url, '/');
+
+ // check for http:// or https:// and validate URL
+ if (strpos($url, 'http://') === 0 || strpos($url, 'https://') === 0) {
+ if (filter_var($url, FILTER_VALIDATE_URL)) {
+ return $url;
+ }
+ } elseif (filter_var("http://" . $url, FILTER_VALIDATE_URL)) {
+ // maybe $url was something like www.example.com
+ return 'http://' . $url;
+ }
+
+ // no valid URL was passed in or could be built from $url
+ throw new NoValidUrlException();
+ }
+
+}
+
+/**
+ * Thrown when no valid url was found by faviconfetcher
+ */
+class NoValidUrlException extends \Exception {
+}
diff --git a/utility/simplepieapifactory.php b/utility/simplepieapifactory.php
new file mode 100644
index 000000000..70e833a4e
--- /dev/null
+++ b/utility/simplepieapifactory.php
@@ -0,0 +1,56 @@
+<?php
+
+/**
+ * ownCloud - App Framework
+ *
+ * @author Bernhard Posselt
+ * @copyright 2012 Bernhard Posselt dev@bernhard-posselt.com
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU AFFERO GENERAL PUBLIC LICENSE for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+namespace OCA\News\Utility;
+
+
+class SimplePieAPIFactory {
+
+ /**
+ * Builds a simplepie file object. This is needed because
+ * the file object contains logic in its constructor which makes it
+ * impossible to inject and test
+ * @return SimplePie_File a new object
+ */
+ public function getFile($url, $timeout=10, $redirects=5, $headers=null,
+ $useragent=null, $force_fsockopen=false) {
+
+ return new \SimplePie_File($url, $timeout, $redirects, $headers,
+ $useragent, $force_fsockopen);
+ }
+
+
+ /**
+ * Returns a new instance of a SimplePie_Core() object. This is needed
+ * because the class relies on external dependencies which are not passed
+ * in via the constructor and thus making it nearly impossible to unittest
+ * code that uses this class
+ * @return \SimplePie_Core instance
+ */
+ public function getCore() {
+ return new \SimplePie_Core();
+ }
+
+
+} \ No newline at end of file
diff --git a/utility/simplepiefilefactory.php b/utility/simplepiefilefactory.php
deleted file mode 100644
index a7a051c23..000000000
--- a/utility/simplepiefilefactory.php
+++ /dev/null
@@ -1,35 +0,0 @@
-<?php
-
-/**
-* ownCloud - News
-*
-* @author Alessandro Cosentino
-* @author Bernhard Posselt
-* @copyright 2012 Alessandro Cosentino cosenal@gmail.com
-* @copyright 2012 Bernhard Posselt dev@bernhard-posselt.com
-*
-* This library is free software; you can redistribute it and/or
-* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
-* License as published by the Free Software Foundation; either
-* version 3 of the License, or any later version.
-*
-* This library is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-* GNU AFFERO GENERAL PUBLIC LICENSE for more details.
-*
-* You should have received a copy of the GNU Affero General Public
-* License along with this library. If not, see <http://www.gnu.org/licenses/>.
-*
-*/
-
-namespace OCA\News\Utility;
-
-
-class SimplePieFileFactory {
-
- public function getFile($url, $timeout, $userAgent = null) {
- return new \SimplePie_File($url, $timeout, 5, null, $userAgent);
- }
-
-}
diff --git a/utility/timefactory.php b/utility/timefactory.php
new file mode 100644
index 000000000..ad97d5915
--- /dev/null
+++ b/utility/timefactory.php
@@ -0,0 +1,42 @@
+<?php
+
+/**
+ * ownCloud - News
+ *
+ * @author Bernhard Posselt
+ * @copyright 2012 Bernhard Posselt dev@bernhard-posselt.com
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU AFFERO GENERAL PUBLIC LICENSE for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+namespace OCA\News\Utility;
+
+
+/**
+ * Needed to mock calls to time()
+ */
+class TimeFactory {
+
+
+ /**
+ * @return int the result of a call to time()
+ */
+ public function getTime() {
+ return time();
+ }
+
+
+} \ No newline at end of file