]> git.mxchange.org Git - quix0rs-gnu-social.git/blobdiff - lib/activityutils.php
Move activity classes to their own files
[quix0rs-gnu-social.git] / lib / activityutils.php
diff --git a/lib/activityutils.php b/lib/activityutils.php
new file mode 100644 (file)
index 0000000..c85a3db
--- /dev/null
@@ -0,0 +1,243 @@
+<?php
+/**
+ * StatusNet, the distributed open-source microblogging tool
+ *
+ * An activity
+ *
+ * PHP version 5
+ *
+ * LICENCE: This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * @category  Feed
+ * @package   StatusNet
+ * @author    Evan Prodromou <evan@status.net>
+ * @author    Zach Copley <zach@status.net>
+ * @copyright 2010 StatusNet, Inc.
+ * @license   http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPLv3
+ * @link      http://status.net/
+ */
+
+if (!defined('STATUSNET')) {
+    exit(1);
+}
+
+/**
+ * Utilities for turning DOMish things into Activityish things
+ *
+ * Some common functions that I didn't have the bandwidth to try to factor
+ * into some kind of reasonable superclass, so just dumped here. Might
+ * be useful to have an ActivityObject parent class or something.
+ *
+ * @category  OStatus
+ * @package   StatusNet
+ * @author    Evan Prodromou <evan@status.net>
+ * @copyright 2010 StatusNet, Inc.
+ * @license   http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPLv3
+ * @link      http://status.net/
+ */
+
+class ActivityUtils
+{
+    const ATOM = 'http://www.w3.org/2005/Atom';
+
+    const LINK = 'link';
+    const REL  = 'rel';
+    const TYPE = 'type';
+    const HREF = 'href';
+
+    const CONTENT = 'content';
+    const SRC     = 'src';
+
+    /**
+     * Get the permalink for an Activity object
+     *
+     * @param DOMElement $element A DOM element
+     *
+     * @return string related link, if any
+     */
+
+    static function getPermalink($element)
+    {
+        return self::getLink($element, 'alternate', 'text/html');
+    }
+
+    /**
+     * Get the permalink for an Activity object
+     *
+     * @param DOMElement $element A DOM element
+     *
+     * @return string related link, if any
+     */
+
+    static function getLink(DOMNode $element, $rel, $type=null)
+    {
+        $els = $element->childNodes;
+
+        foreach ($els as $link) {
+
+            if (!($link instanceof DOMElement)) {
+                continue;
+            }
+
+            if ($link->localName == self::LINK && $link->namespaceURI == self::ATOM) {
+
+                $linkRel = $link->getAttribute(self::REL);
+                $linkType = $link->getAttribute(self::TYPE);
+
+                if ($linkRel == $rel &&
+                    (is_null($type) || $linkType == $type)) {
+                    return $link->getAttribute(self::HREF);
+                }
+            }
+        }
+
+        return null;
+    }
+
+    static function getLinks(DOMNode $element, $rel, $type=null)
+    {
+        $els = $element->childNodes;
+        $out = array();
+
+        foreach ($els as $link) {
+            if ($link->localName == self::LINK && $link->namespaceURI == self::ATOM) {
+
+                $linkRel = $link->getAttribute(self::REL);
+                $linkType = $link->getAttribute(self::TYPE);
+
+                if ($linkRel == $rel &&
+                    (is_null($type) || $linkType == $type)) {
+                    $out[] = $link;
+                }
+            }
+        }
+
+        return $out;
+    }
+
+    /**
+     * Gets the first child element with the given tag
+     *
+     * @param DOMElement $element   element to pick at
+     * @param string     $tag       tag to look for
+     * @param string     $namespace Namespace to look under
+     *
+     * @return DOMElement found element or null
+     */
+
+    static function child(DOMNode $element, $tag, $namespace=self::ATOM)
+    {
+        $els = $element->childNodes;
+        if (empty($els) || $els->length == 0) {
+            return null;
+        } else {
+            for ($i = 0; $i < $els->length; $i++) {
+                $el = $els->item($i);
+                if ($el->localName == $tag && $el->namespaceURI == $namespace) {
+                    return $el;
+                }
+            }
+        }
+    }
+
+    /**
+     * Grab the text content of a DOM element child of the current element
+     *
+     * @param DOMElement $element   Element whose children we examine
+     * @param string     $tag       Tag to look up
+     * @param string     $namespace Namespace to use, defaults to Atom
+     *
+     * @return string content of the child
+     */
+
+    static function childContent(DOMNode $element, $tag, $namespace=self::ATOM)
+    {
+        $el = self::child($element, $tag, $namespace);
+
+        if (empty($el)) {
+            return null;
+        } else {
+            return $el->textContent;
+        }
+    }
+
+    static function childHtmlContent(DOMNode $element, $tag, $namespace=self::ATOM)
+    {
+        $el = self::child($element, $tag, $namespace);
+
+        if (empty($el)) {
+            return null;
+        } else {
+            return self::textConstruct($el);
+        }
+    }
+
+    /**
+     * Get the content of an atom:entry-like object
+     *
+     * @param DOMElement $element The element to examine.
+     *
+     * @return string unencoded HTML content of the element, like "This -&lt; is <b>HTML</b>."
+     *
+     * @todo handle remote content
+     * @todo handle embedded XML mime types
+     * @todo handle base64-encoded non-XML and non-text mime types
+     */
+
+    static function getContent($element)
+    {
+        return self::childHtmlContent($element, self::CONTENT, self::ATOM);
+    }
+
+    static function textConstruct($el)
+    {
+        $src  = $el->getAttribute(self::SRC);
+
+        if (!empty($src)) {
+            throw new ClientException(_("Can't handle remote content yet."));
+        }
+
+        $type = $el->getAttribute(self::TYPE);
+
+        // slavishly following http://atompub.org/rfc4287.html#rfc.section.4.1.3.3
+
+        if (empty($type) || $type == 'text') {
+            return $el->textContent;
+        } else if ($type == 'html') {
+            $text = $el->textContent;
+            return htmlspecialchars_decode($text, ENT_QUOTES);
+        } else if ($type == 'xhtml') {
+            $divEl = ActivityUtils::child($el, 'div', 'http://www.w3.org/1999/xhtml');
+            if (empty($divEl)) {
+                return null;
+            }
+            $doc = $divEl->ownerDocument;
+            $text = '';
+            $children = $divEl->childNodes;
+
+            for ($i = 0; $i < $children->length; $i++) {
+                $child = $children->item($i);
+                $text .= $doc->saveXML($child);
+            }
+            return trim($text);
+        } else if (in_array($type, array('text/xml', 'application/xml')) ||
+                   preg_match('#(+|/)xml$#', $type)) {
+            throw new ClientException(_("Can't handle embedded XML content yet."));
+        } else if (strncasecmp($type, 'text/', 5)) {
+            return $el->textContent;
+        } else {
+            throw new ClientException(_("Can't handle embedded Base64 content yet."));
+        }
+    }
+}