1<?php
2/**
3 * SIOC Exporter API.
4 *
5 * Allow people to easilly create their own SIOC Exporter for any PHP application
6 *
7 * @package sioc_inc
8 * @author  Alexandre Passant <alex@passant.org>
9 * @author  Uldis Bojars <captsolo@gmail.com> (adaptation to PHP4)
10 * @author  Thomas Schandl <tom.schandl@gmail.com> (addition of SIOCThread)
11 * @author  Fabrizio Orlandi <fabrizio.orlandi@deri.org> (addition of SIOCWIki SIOCWikiArticle SIOCCategory)
12 *
13 * @phpcs:disable PSR1.Classes.ClassDeclaration.MultipleClasses
14 */
15
16const AUTHORS_NODE     = 'authors';
17const EXPORTER_URL     = 'http://wiki.sioc-project.org/index.php/PHPExportAPI';
18const EXPORTER_VERSION = '1.01';
19
20/**
21 * Main exporter class.
22 *
23 * Generates RDF/XML content of SIOC export.
24 * - Sets up parameters for generating RDF/XML
25 * - Sets up parameters for SIOC URL generation
26 */
27class SIOCExporter
28{
29
30    public $profile_url;
31    private $title;
32    private $blog_url;
33    private $sioc_url;
34    private $encoding;
35    private $generator;
36    private $urlseparator;
37    private $urlequal;
38    private $url4type; // e.g. type   or   sioc_type
39    private $url4id; // TS e. g.  id    or sioc_id
40    private $url4page;
41    // TS: if true: appends the "type" of a class to the url4id in order to compose the string for the "id part"
42    // of the siocURL. e. g. for a forum that could produce "forum_id=" or "forum_sioc_id="
43    private $url_usetype;
44    private $url_suffix; // TS:  custom parameter to be appended at the end of a siocURL
45    private $type_table;
46    private $ignore_suffix; // TS: for types in this table the url_suffix  won't be appended to their siocURL
47    private $export_email;
48    private $objects;
49
50    public function __construct()
51    {
52        $this->urlseparator  = '&';
53        $this->urlequal      = '=';
54        $this->url4type      = 'type';
55        $this->url4id        = 'id';
56        $this->url4page      = 'page';
57        $this->url_usetype   = true;
58        $this->url_suffix    = '';
59        $this->type_table    = array();
60        $this->ignore_suffix = array();
61        $this->export_email  = false;
62        $this->encoding      = 'UTF-8';
63        $this->objects       = array();
64    }
65
66    public function setURLParameters(
67        $type = 'type',
68        $id = 'id',
69        $page = 'page',
70        $url_usetype = true,
71        $urlseparator = '&',
72        $urlequal = '=',
73        $suffix = ''
74    ) {
75        $this->urlseparator = $urlseparator;
76        $this->urlequal     = $urlequal;
77        $this->url4type     = $type;
78        $this->url4id       = $id;
79        $this->url4page     = $page;
80        $this->url_usetype  = $url_usetype;
81        $this->url_suffix   = $suffix;
82    }
83
84    public function setParameters($title, $url, $sioc_url, $encoding, $generator, $export_email = false)
85    {
86        $this->title        = $title;
87        $this->blog_url     = $url;
88        $this->sioc_url     = $sioc_url;
89        $this->encoding     = $encoding;
90        $this->generator    = $generator;
91        $this->export_email = $export_email;
92    }
93
94    // Assigns some objects to the exporter
95    public function addObject(&$obj)
96    {
97        $this->objects[] = &$obj;
98    }
99
100    // TS: Used to replace url4id in the siocURL for a given type (site, forum, etc.) with a
101    // parameter ($name) of your choice
102    // E.g. b2evo exporter uses "blog=" instead of "sioc_id=" in the siocURL of a forum
103    public function setURLTypeParm($type, $name)
104    {
105        $this->type_table[$type] = $name;
106    }
107
108    public function setSuffixIgnore($type)
109    {
110        $this->ignore_suffix[$type] = 1;
111    }
112
113    public function siocURL($type, $id, $page = "")
114    {
115        $type_part = $this->url4type . $this->urlequal . $type;
116
117        if ($id) {
118            if (isset($this->type_table[$type])) {
119                $myID = $this->type_table[$type];
120            } else {
121                $myID = (($this->url_usetype) ? $type . '_' : '') . $this->url4id;
122            }
123
124            $id_part = $this->urlseparator . $myID . $this->urlequal . $id;
125        } else {
126            $id_part = '';
127        }
128
129        ($page) ? $page_part = $this->urlseparator . $this->url4page . $this->urlequal . $page : $page_part = '';
130
131        ($this->url_suffix && !isset($this->ignore_suffix[$type])) ?
132            $suffix = $this->urlseparator . $this->url_suffix : $suffix = '';
133
134        $siocURL = $this->sioc_url . $type_part . $id_part . $page_part . $suffix;
135        return clean($siocURL, true);
136    }
137
138    public function export($rdf_content = '')
139    {
140        header('Content-Type: application/rdf+xml; charset=' . $this->encoding,
141               true, 200);
142        echo $this->makeRDF($rdf_content);
143    }
144
145    public function makeRDF($rdf_content = '')
146    {
147        $rdf = '<?xml version="1.0" encoding="' . $this->encoding . '" ?>' . "\n";
148        $rdf .= '
149<rdf:RDF
150    xmlns="http://xmlns.com/foaf/0.1/"
151    xmlns:foaf="http://xmlns.com/foaf/0.1/"
152    xmlns:admin="http://webns.net/mvcb/"
153    xmlns:content="http://purl.org/rss/1.0/modules/content/"
154    xmlns:dc="http://purl.org/dc/elements/1.1/"
155    xmlns:dcterms="http://purl.org/dc/terms/"
156    xmlns:dcmitype="http://purl.org/dc/dcmitype/"
157    xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
158    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
159    xmlns:sioc="http://rdfs.org/sioc/ns#"
160    xmlns:sioct="http://rdfs.org/sioc/types#"
161    xmlns:owl="http://www.w3.org/2002/07/owl">
162<foaf:Document rdf:about="' . clean($this->profile_url, true) . '">
163	<dc:title>"' . clean($this->title) . '" (SIOC profile)</dc:title>
164	<foaf:primaryTopic rdf:resource="' . clean($this->objects[0]->_url, true) . '"/>
165	<admin:generatorAgent rdf:resource="' . clean($this->generator, true) . '"/>
166	<admin:generatorAgent rdf:resource="' . clean(EXPORTER_URL, true) . '?version=' . EXPORTER_VERSION . '"/>
167</foaf:Document>' . "\n";
168        if ($rdf_content) {
169            $rdf .= $rdf_content;
170        }
171        if (count($this->objects)) {
172            foreach ($this->objects as $object) {
173                if ($object) {
174                    $rdf .= $object->getContent($this);
175                }
176            }
177        }
178        $rdf .= "\n</rdf:RDF>";
179        return $rdf;
180    }
181}
182
183/**
184 * Generic SIOC Object
185 *
186 * All SIOC objects are derived from this.
187 */
188class SIOCObject
189{
190    protected $note = '';
191
192    public function addNote($note)
193    {
194        $this->note = $note;
195    }
196
197    public function getContent(&$exp): string
198    {
199        $rdf = "<sioc:Object>\n";
200        $rdf .= "    <rdfs:comment>Generic SIOC Object</rdfs:comment>\n";
201        $rdf .= "</sioc:Object>\n";
202        return $rdf;
203    }
204}
205
206/**
207 * SIOC::Site object
208 *
209 * Contains information about main SIOC page including:
210 *  - site description
211 *  - list of forums
212 *  - list of users
213 */
214class SIOCSite extends SIOCObject
215{
216
217    private $type = 'site';
218
219    private $url;
220    private $name;
221    private $description;
222    private $forums;
223    private $users;
224    private $page;
225    private $next_users;
226    private $next_forums;
227    private $usergroup_uri;
228
229    public function __construct($url, $name, $description, $page = '', $usergroup_uri = '')
230    {
231        $this->url           = $url;
232        $this->name          = $name;
233        $this->description   = $description;
234        $this->forums        = array();
235        $this->users         = array();
236        $this->page          = $page;
237        $this->next_users    = false;
238        $this->next_forums   = false;
239        $this->usergroup_uri = $usergroup_uri;
240    }
241
242    public function addForum($id, $url)
243    {
244        $this->forums[$id] = $url;
245    }
246
247    public function addUser($id, $url)
248    {
249        $this->users[$id] = $url;
250    }
251
252    public function setNextPageUsers($next)
253    {
254        $this->next_users = $next;
255    }
256
257    public function setNextPageForums($next)
258    {
259        $this->next_forums = $next;
260    }
261
262    public function getContent(&$exp): string
263    {
264        $rdf = "<sioc:Site rdf:about=\"" . clean($this->url) . "\">\n";
265        $rdf .= "    <dc:title>" . clean($this->name) . "</dc:title>\n";
266        $rdf .= "    <dc:description>" . clean($this->description) . "</dc:description>\n";
267        $rdf .= "    <sioc:link rdf:resource=\"" . clean($this->url) . "\"/>\n";
268        if ($this->forums) {
269            foreach ($this->forums as $id => $url) {
270                $rdf .= "    <sioc:host_of rdf:resource=\"" . clean($url) . "\"/>\n";
271            }
272        }
273        if ($this->next_forums) {
274            $rdf .= "    <rdfs:seeAlso rdf:resource=\"" . $exp->siocURL('site', "", $this->page + 1) . "\"/>\n";
275        }
276        if ($this->usergroup_uri) {
277            $rdf .= "    <sioc:has_Usergroup rdf:resource=\"" . $this->usergroup_uri . "\"/>\n";
278        } else {
279            $rdf .= "    <sioc:has_Usergroup rdf:nodeID=\"" . AUTHORS_NODE . "\"/>\n";
280        }
281        $rdf .= "</sioc:Site>\n";
282        // Forums
283        if ($this->forums) {
284            $rdf .= "\n";
285            foreach ($this->forums as $id => $url) {
286                $rdf .= '<sioc:Forum rdf:about="' . clean($url) . "\">\n";
287                $rdf .= "    <sioc:link rdf:resource=\"" . clean($url) . "\"/>\n";
288                $rdf .= "    <rdfs:seeAlso rdf:resource=\"" . $exp->siocURL('forum', $id) . "\"/>\n";
289                $rdf .= "</sioc:Forum>\n";
290            }
291        }
292        // Usergroup
293        if ($this->users) {
294            $rdf .= "\n";
295            if ($this->usergroup_uri) {
296                $rdf .= '<sioc:UserAccountgroup rdf:about="' . $this->usergroup_uri . "\">\n";
297            } else {
298                $rdf .= '<sioc:UserAccountgroup rdf:nodeID="' . AUTHORS_NODE . "\">\n";
299            }
300            $rdf .= "    <sioc:name>Authors for \"" . clean($this->name) . "\"</sioc:name>\n";
301            foreach ($this->users as $id => $url) {
302                $rdf .= "    <sioc:has_member>\n";
303                $rdf .= "        <sioc:UserAccount rdf:about=\"" . clean($url) . "\">\n";
304                $rdf .= "            <rdfs:seeAlso rdf:resource=\"" . $exp->siocURL('user', $id) . "\"/>\n";
305                $rdf .= "        </sioc:UserAccount>\n";
306                $rdf .= "    </sioc:has_member>\n";
307            }
308            if ($this->next_users) {
309                $rdf .= "    <rdfs:seeAlso rdf:resource=\"" . $exp->siocURL('site', "", $this->page + 1) . "\"/>\n";
310            }
311            $rdf .= "</sioc:UserAccountgroup>\n";
312        }
313
314        return $rdf;
315    }
316}
317
318// Export detaille d'un utilisateur
319
320/**
321 * SIOC::User object
322 *
323 * Contains user profile information
324 */
325class SIOCUser extends SIOCObject
326{
327
328    private $type = 'user';
329
330    private $id;
331    private $nick;
332    private $uri;
333    private $name;
334    private $email;
335    private $sha1;
336    private $homepage;
337    private $foaf_uri;
338    private $role;
339    private $sioc_url;
340    private $foaf_url;
341
342    public function __construct(
343        $id,
344        $uri,
345        $name,
346        $email,
347        $homepage = '',
348        $foaf_uri = '',
349        $role = false,
350        $nick = '',
351        $sioc_url = '',
352        $foaf_url = ''
353    ) {
354        $this->id   = $id;
355        $this->uri  = $uri;
356        $this->name = $name;
357
358        if (preg_match_all('/^.+@.+\..+$/Ui', $email, $check, PREG_SET_ORDER)) {
359            if (preg_match_all('/^mailto:(.+@.+\..+$)/Ui', $email, $matches, PREG_SET_ORDER)) {
360                $this->email = $email;
361                $this->sha1  = sha1($email);
362            } else {
363                $this->email = "mailto:" . $email;
364                $this->sha1  = sha1("mailto:" . $email);
365            }
366        }
367        $this->homepage = $homepage;
368        $this->foaf_uri = $foaf_uri;
369        $this->_url     = $foaf_uri;
370        $this->role     = $role;
371        $this->nick     = $nick;
372        $this->foaf_url = $foaf_url;
373        $this->sioc_url = $sioc_url;
374    }
375
376    public function getContent(&$exp): string
377    {
378        $rdf = "<foaf:Person rdf:about=\"" . clean($this->foaf_uri) . "\">\n";
379        if ($this->name) {
380            $rdf .= "    <foaf:name>" . $this->name . "</foaf:name>\n";
381        }
382        if ($this->email) {
383            $rdf .= "    <foaf:mbox_sha1sum>" . $this->sha1 . "</foaf:mbox_sha1sum>\n";
384        }
385        if ($this->foaf_url) {
386            $rdf .= "    <rdfs:seeAlso rdf:resource=\"" . $this->foaf_url . "\"/>\n";
387        }
388        $rdf .= "    <foaf:holdsAccount>\n";
389        $rdf .= "        <sioc:UserAccount rdf:about=\"" . clean($this->uri) . "\">\n";
390        if ($this->nick) {
391            $rdf .= "            <sioc:name>" . $this->nick . "</sioc:name>\n";
392        }
393        if ($this->email) {
394            if ($exp->_export_email) {
395                $rdf .= "            <sioc:email rdf:resource=\"" . $this->email . "\"/>\n";
396            }
397            $rdf .= "            <sioc:email_sha1>" . $this->sha1 . "</sioc:email_sha1>\n";
398        }
399        if ($this->role) {
400            $rdf .= "            <sioc:has_function>\n";
401            $rdf .= "                <sioc:Role>\n";
402            $rdf .= "                    <sioc:name>" . $this->role . "</sioc:name>\n";
403            $rdf .= "                </sioc:Role>\n";
404            $rdf .= "            </sioc:has_function>\n";
405        }
406        if ($this->sioc_url) {
407            $rdf .= "            <rdfs:seeAlso rdf:resource=\"" . $this->sioc_url . "\"/>\n";
408        }
409        $rdf .= "        </sioc:UserAccount>\n";
410        $rdf .= "    </foaf:holdsAccount>\n";
411        $rdf .= "</foaf:Person>\n";
412        return $rdf;
413    }
414}
415
416// Export detaille d'un utilisateur
417
418/**
419 * SIOC::Thread object
420 *
421 * Contains information about a SIOC Thread in a SIOC Forum
422 * - list of posts in that thread
423 */
424class SIOCThread extends SIOCObject
425{
426
427    private $type = 'thread';
428    private $id;
429    private $url;
430    private $page;
431    private $posts;
432    private $next;
433    private $views;
434    private $tags;
435    private $related;
436    private $title;
437    private $created;
438    private $parents;
439    /**
440     * @var mixed|string
441     */
442    private $subject;
443
444    public function __construct($id, $url, $page, $views = '', $tags = array(), $subject = '', $created = '')
445    {
446        $this->id      = $id;
447        $this->url     = $url;
448        $this->page    = $page;
449        $this->posts   = array();
450        $this->next    = false;
451        $this->views   = $views;
452        $this->tags    = $tags;
453        $this->related = array();
454        $this->subject = $subject;
455        $this->created = $created;
456    }
457
458    public function addPost($id, $url, $prev = '', $next = '')
459    {
460        $this->posts[$id] = array("url" => $url, "prev" => $prev, "next" => $next);
461    }
462
463    // add links to things that are similar to this via sioc:related_to
464    public function addRelated($id, $url)
465    {
466        $this->related[$id] = $url;
467    }
468
469    public function setNextPage($next)
470    {
471        $this->next = $next;
472    }
473
474    public function addParentForum($id, $url)
475    {
476        $this->parents[$id] = $url;
477    }
478
479    public function getContent(&$exp): string
480    {
481        $rdf = '<sioc:Thread rdf:about="' . clean($this->url) . "\">\n";
482        $rdf .= "    <sioc:link rdf:resource=\"" . clean($this->url) . "\"/>\n";
483        if ($this->views) {
484            $rdf .= "    <sioc:num_views>" . $this->views . "</sioc:num_views>\n";
485        }
486        if ($this->note) {
487            $rdf .= "    <rdfs:comment>" . $this->note . "</rdfs:comment>\n";
488        }
489        if ($this->subject) {
490            $rdf .= "    <dc:title>" . $this->subject . "</dc:title>\n";
491        }
492        if ($this->created) {
493            $rdf .= "    <dcterms:created>" . $this->created . "</dcterms:created>\n";
494        }
495        if ($this->parents) {
496            foreach ($this->parents as $id => $uri) {
497                $rdf .= "    <sioc:has_parent>\n";
498                $rdf .= "        <sioc:Forum rdf:about=\"" . clean($uri) . "\">\n";
499                $rdf .= "            <rdfs:seeAlso rdf:resource=\"" . $exp->siocURL('forum', $id) . "\"/>\n";
500                $rdf .= "        </sioc:Forum>\n";
501                $rdf .= "    </sioc:has_parent>\n";
502            }
503        }
504        // here the tags are just used as keywords for dc:subject
505        if ($this->tags) {
506            foreach ($this->tags as $id => $tag) {
507                $rdf .= "    <dc:subject>" . $tag . "</dc:subject>\n";
508            }
509        }
510        // here the tags are used by creating a tag object with a blank node, with the keyword as moat:name - if you
511        // use this insert prefixes for moat and tags
512        // if ($this->tags) {
513        // $i=1;
514        // foreach ($this->tags as $id => $tag) {
515        // $rdf .= "    <tags:taggedWithTag>\n";
516        // $rdf .= "        <moat:tag rdf:nodeID=\"b$i\">\n";
517        // // actually, the best way is to have 'reference URIs' for tags, e.g. URIs for all the platform
518        // (http://tags.example.org/tag/soccer
519        // $rdf .= "            <moat:name>" . $tag . "</moat:name>\n";
520        // $rdf .= "        </moat:tag>\n";
521        // $rdf .= "    </moat:taggedWithTag>\n";
522        // $i++;
523        // }
524        // }
525
526        // here the tags are used are used for sioc:topic, each topic needs to have a URI
527        /*if($this->tags) {
528                foreach($this->tags as $url=>$topic) {
529                    $rdf .= "    <sioc:topic rdfs:label=\"$topic\" rdf:resource=\"" . clean($url) ."\"/>\n";
530                }
531            }
532            */
533        if ($this->related) {
534            foreach ($this->related as $id => $url) {
535                $rdf .= "    <sioc:related_to>\n";
536                $rdf .= "        <sioc:Thread rdf:about=\"" . clean($url) . "\"/>\n";
537                $rdf .= "    </sioc:related_to>\n"; // todo - each topic needs to have a URI
538            }
539        }
540
541        if ($this->posts) {
542            foreach ($this->posts as $id => $data) {
543                $rdf .= "    <sioc:container_of>\n";
544                $rdf .= "        <sioc:Post rdf:about=\"" . clean($data[url]) . "\">\n";
545                $rdf .= "            <rdfs:seeAlso rdf:resource=\"" . $exp->siocURL('post', $id) . "\"/>\n";
546                if ($data[prev]) {
547                    $rdf .= "            <sioc:previous_by_date rdf:resource=\"" . clean($data[prev]) . "\"/>\n";
548                }
549                if ($data[next]) {
550                    $rdf .= "            <sioc:next_by_date rdf:resource=\"" . clean($data[next]) . "\"/>\n";
551                }
552                $rdf .= "        </sioc:Post>\n";
553                $rdf .= "    </sioc:container_of>\n";
554            }
555        }
556        if ($this->next) {
557            $rdf .= "\r<rdfs:seeAlso rdf:resource=\"" . $exp->siocURL('thread', $this->id, $this->page + 1) . "\"/>\n";
558        }
559        $rdf .= "</sioc:Thread>\n";
560        return $rdf;
561    }
562}
563
564// Export d'un forum avec une liste de posts -variable (next with seeAlso)
565
566/**
567 * SIOC::Forum object
568 *
569 * Contains information about SIOC Forum (blog, ...):
570 *  - description of a forum
571 *  - list of posts within a forum [partial, paged]
572 */
573class SIOCForum extends SIOCObject
574{
575
576    private $type = 'forum';
577
578    private $id;
579    private $url;
580    private $page;
581    private $posts;
582    private $next;
583    private $blog_title;
584    private $description;
585    private $threads;
586    private $parents;
587    private $creator;
588    private $administrator;
589    /**
590     * @var array|mixed
591     */
592    private $links;
593
594    public function __construct(
595        $id,
596        $url,
597        $page,
598        $title = '',
599        $descr = '',
600        $type = 'sioc:Forum',
601        $creator = '',
602        $admin = '',
603        $links = array()
604    ) {
605        $this->id            = $id;
606        $this->url           = $url;
607        $this->page          = $page;
608        $this->posts         = array();
609        $this->next          = false;
610        $this->blog_title    = $title;
611        $this->description   = $descr;
612        $this->threads       = array();
613        $this->parents       = array();
614        $this->_type         = $type;
615        $this->creator       = $creator;
616        $this->administrator = $admin;
617        $this->links         = $links;
618    }
619
620    public function addPost($id, $url)
621    {
622        $this->posts[$id] = $url;
623    }
624
625    public function addThread($id, $url)
626    {
627        $this->threads[$id] = $url;
628    }
629
630    public function addParentForum($id, $url)
631    {
632        $this->parents[$id] = $url;
633    }
634
635    public function setNextPage($next)
636    {
637        $this->next = $next;
638    }
639
640    public function getContent(&$exp): string
641    {
642        $rdf = '<' . $this->_type . ' rdf:about="' . clean($this->url) . "\">\n";
643        if ($this->_type != 'sioc:Forum') {
644            $rdf .= "    <rdf:type rdf:resource=\"http://rdfs.org/sioc/ns#Forum\" />\n";
645        }
646        $rdf .= "    <sioc:link rdf:resource=\"" . clean($this->url) . "\"/>\n";
647        if ($this->blog_title) {
648            $rdf .= "    <dc:title>" . $this->blog_title . "</dc:title>\n";
649        }
650        if ($this->description) {
651            $rdf .= "    <dc:description>" . $this->description . "</dc:description>\n";
652        }
653        if ($this->note) {
654            $rdf .= "    <rdfs:comment>" . $this->note . "</rdfs:comment>\n";
655        }
656
657        if ($this->parents) {
658            foreach ($this->parents as $id => $uri) {
659                $rdf .= "    <sioc:has_parent>\n";
660                $rdf .= "        <sioc:Forum rdf:about=\"" . clean($uri) . "\">\n";
661                $rdf .= "            <rdfs:seeAlso rdf:resource=\"" . $exp->siocURL('forum', $id) . "\"/>\n";
662                $rdf .= "        </sioc:Forum>\n";
663                $rdf .= "    </sioc:has_parent>\n";
664            }
665        }
666
667        if ($this->threads) {
668            foreach ($this->threads as $id => $uri) {
669                $rdf .= "    <sioc:parent_of>\n";
670                $rdf .= "        <sioc:Thread rdf:about=\"" . clean($uri) . "\">\n";
671                $rdf .= "            <rdfs:seeAlso rdf:resource=\"" . $exp->siocURL('thread', $id) . "\"/>\n";
672                $rdf .= "        </sioc:Thread>\n";
673                $rdf .= "    </sioc:parent_of>\n";
674            }
675        }
676
677        if ($this->posts) {
678            foreach ($this->posts as $id => $url) {
679                $rdf .= "    <sioc:container_of>\n";
680                $rdf .= "        <sioc:Post rdf:about=\"" . clean($url) . "\">\n";
681                $rdf .= "            <rdfs:seeAlso rdf:resource=\"" . $exp->siocURL('post', $id) . "\"/>\n";
682                $rdf .= "        </sioc:Post>\n";
683                $rdf .= "    </sioc:container_of>\n";
684            }
685        }
686
687        if ($this->creator) {
688            if ($this->creator->_id) {
689                $rdf .= "    <sioc:has_creator>\n";
690                $rdf .= "        <sioc:UserAccount rdf:about=\"" . clean($this->creator->_uri) . "\">\n";
691                if ($this->creator->_sioc_url) {
692                    $rdf .= "            <rdfs:seeAlso rdf:resource=\"" . $this->creator->_sioc_url . "\"/>\n";
693                } else {
694                    $rdf .= "            <rdfs:seeAlso rdf:resource=\"" . $exp->siocURL(
695                            'user',
696                            $this->creator->_id
697                        ) . "\"/>\n";
698                }
699                $rdf .= "        </sioc:UserAccount>\n";
700                $rdf .= "    </sioc:has_creator>\n";
701                $rdf .= "    <foaf:maker>\n";
702                $rdf .= "        <foaf:Person rdf:about=\"" . clean($this->creator->_foaf_uri) . "\">\n";
703                if ($this->creator->_foaf_url) {
704                    $rdf .= "            <rdfs:seeAlso rdf:resource=\"" . $this->creator->_foaf_url . "\"/>\n";
705                } else {
706                    $rdf .= "            <rdfs:seeAlso rdf:resource=\"" . $exp->siocURL(
707                            'user',
708                            $this->creator->_id
709                        ) . "\"/>\n";
710                }
711                $rdf .= "        </foaf:Person>\n";
712                $rdf .= "    </foaf:maker>\n";
713            } else {
714                $rdf .= "    <foaf:maker>\n";
715                $rdf .= "        <foaf:Person";
716                if ($this->creator->_name) {
717                    $rdf .= " foaf:name=\"" . $this->creator->_name . "\"";
718                }
719                if ($this->creator->_sha1) {
720                    $rdf .= " foaf:mbox_sha1sum=\"" . $this->creator->_sha1 . "\"";
721                }
722                if ($this->creator->_name) {
723                    $rdf .= ">\n<foaf:homepage rdf:resource=\"" . $this->creator->_homepage . "\"/>\n</foaf:Person>\n";
724                } else {
725                    $rdf .= "/>\n";
726                }
727                $rdf .= "    </foaf:maker>\n";
728            }
729        }
730
731        if ($this->administrator) {
732            if ($this->administrator->_id) {
733                $rdf .= "    <sioc:has_administrator>\n";
734                $rdf .= "        <sioc:UserAccount rdf:about=\"" . clean($this->administrator->_uri) . "\">\n";
735                if ($this->administrator->_sioc_url) {
736                    $rdf .= "            <rdfs:seeAlso rdf:resource=\"" . $this->administrator->_sioc_url . "\"/>\n";
737                } else {
738                    $rdf .= "            <rdfs:seeAlso rdf:resource=\"" . $exp->siocURL(
739                            'user',
740                            $this->administrator->_id
741                        ) . "\"/>\n";
742                }
743                $rdf .= "        </sioc:UserAccount>\n";
744                $rdf .= "    </sioc:has_administrator>\n";
745            }
746        }
747        if ($this->links) {
748            foreach ($this->links as $url => $link) {
749                $rdf .= "    <sioc:links_to rdfs:label=\"$link\" rdf:resource=\"" . clean($url) . "\"/>\n";
750            }
751        }
752
753        if ($this->next) {
754            $rdf .= "\r<rdfs:seeAlso rdf:resource=\"" . $exp->siocURL('forum', $this->id, $this->page + 1) . "\"/>\n";
755        }
756        $rdf .= "</" . $this->_type . ">";
757
758        return $rdf;
759    }
760}
761
762/**
763 * SIOC::Post object
764 *
765 * Contains information about a post
766 */
767class SIOCPost extends SIOCObject
768{
769
770    private $type = 'post';
771
772    private $url;
773    private $subject;
774    private $content;
775    private $encoded;
776    private $creator;
777    private $created;
778    private $updated;
779    private $topics;
780    private $links;
781    private $comments;
782    private $reply_of;
783    private $has_part;
784
785    public function __construct(
786        $url,
787        $subject,
788        $content,
789        $encoded,
790        $creator,
791        $created,
792        $updated = "",
793        $topics = array(),
794        $links = array(),
795        $type = 'sioc:Post',
796        $has_part = array()
797    ) {
798        $this->url      = $url;
799        $this->subject  = $subject;
800        $this->content  = $content;
801        $this->encoded  = $encoded;
802        $this->creator  = $creator;
803        $this->created  = $created;
804        $this->updated  = $updated;
805        $this->topics   = $topics;
806        $this->links    = $links;
807        $this->comments = array();
808        $this->reply_of = array();
809        $this->_type    = $type;
810        $this->has_part = $has_part;
811    }
812
813    public function addComment($id, $url)
814    {
815        $this->comments[$id] = $url;
816    }
817
818    public function addReplyOf($id, $url)
819    {
820        $this->reply_of[$id] = $url;
821    }
822
823    public function getContent(&$exp): string
824    {
825        $rdf = '<' . $this->_type . " rdf:about=\"" . clean($this->url) . "\">\n";
826        if ($this->_type != 'sioc:Post') {
827            $rdf .= "    <rdf:type rdf:resource=\"http://rdfs.org/sioc/ns#Post\" />\n";
828        }
829        if ($this->subject) {
830            $rdf .= "    <dc:title>" . $this->subject . "</dc:title>\n";
831        }
832        if ($this->creator) {
833            if ($this->creator->_id) {
834                $rdf .= "    <sioc:has_creator>\n";
835                $rdf .= "        <sioc:UserAccount rdf:about=\"" . clean($this->creator->_uri) . "\">\n";
836                if ($this->creator->_sioc_url) {
837                    $rdf .= "            <rdfs:seeAlso rdf:resource=\"" . $this->creator->_sioc_url . "\"/>\n";
838                } else {
839                    $rdf .= "            <rdfs:seeAlso rdf:resource=\"" . $exp->siocURL(
840                            'user',
841                            $this->creator->_id
842                        ) . "\"/>\n";
843                }
844                $rdf .= "        </sioc:UserAccount>\n";
845                $rdf .= "    </sioc:has_creator>\n";
846                $rdf .= "    <foaf:maker>\n";
847                $rdf .= "        <foaf:Person rdf:about=\"" . clean($this->creator->_foaf_uri) . "\">\n";
848                if ($this->creator->_foaf_url) {
849                    $rdf .= "            <rdfs:seeAlso rdf:resource=\"" . $this->creator->_foaf_url . "\"/>\n";
850                } else {
851                    $rdf .= "            <rdfs:seeAlso rdf:resource=\"" . $exp->siocURL(
852                            'user',
853                            $this->creator->_id
854                        ) . "\"/>\n";
855                }
856                $rdf .= "        </foaf:Person>\n";
857                $rdf .= "    </foaf:maker>\n";
858            } else {
859                $rdf .= "    <foaf:maker>\n";
860                $rdf .= "        <foaf:Person";
861                if ($this->creator->_name) {
862                    $rdf .= " foaf:name=\"" . $this->creator->_name . "\"";
863                }
864                if ($this->creator->_sha1) {
865                    $rdf .= " foaf:mbox_sha1sum=\"" . $this->creator->_sha1 . "\"";
866                }
867                if ($this->creator->_name) {
868                    $rdf .= ">\n<foaf:homepage rdf:resource=\"" . $this->creator->_homepage . "\"/>\n</foaf:Person>\n";
869                } else {
870                    $rdf .= "/>\n";
871                }
872                $rdf .= "    </foaf:maker>\n";
873            }
874        }
875        $rdf .= "    <dcterms:created>" . $this->created . "</dcterms:created>\n";
876        if ($this->updated and ($this->created != $this->updated)) {
877            $rdf .= "    <dcterms:modified>" . $this->updated . "</dcterms:modified>\n";
878        }
879        $rdf .= "    <sioc:content>" . pureContent($this->content) . "</sioc:content>\n";
880
881        $rdf .= "    <content:encoded><![CDATA[" . $this->encoded . "]]></content:encoded>\n";
882        if ($this->topics) {
883            foreach ($this->topics as $url => $topic) {
884                $rdf .= "    <sioc:topic rdfs:label=\"$topic\" rdf:resource=\"" . clean($url) . "\"/>\n";
885            }
886        }
887        if ($this->links) {
888            foreach ($this->links as $url => $link) {
889                $rdf .= "    <sioc:links_to rdfs:label=\"$link\" rdf:resource=\"" . clean($url) . "\"/>\n";
890            }
891        }
892        if ($this->has_part) {
893            foreach ($this->has_part as $id => $url) {
894                $rdf .= "    <dcterms:hasPart>\n";
895                $rdf .= "        <dcmitype:Image rdf:about=\"" . clean($url) . "\"/>\n";
896                $rdf .= "    </dcterms:hasPart>\n";
897            }
898        }
899        if ($this->reply_of) {
900            foreach ($this->reply_of as $id => $url) {
901                $rdf .= "    <sioc:reply_of>\n";
902                $rdf .= "        <sioc:Post rdf:about=\"" . clean($url) . "\">\n";
903                $rdf .= "            <rdfs:seeAlso rdf:resource=\"" . $exp->siocURL('post', $id) . "\"/>\n";
904                $rdf .= "        </sioc:Post>\n";
905                $rdf .= "    </sioc:reply_of>\n";
906            }
907        }
908        if ($this->comments) {
909            foreach ($this->comments as $id => $url) {
910                $rdf .= "    <sioc:has_reply>\n";
911                $rdf .= "        <sioc:Post rdf:about=\"" . clean($url) . "\">\n";
912                //        if($comments->f('comment_trackback')) $rdf .= "            <sioc:type>"
913                // . POST_TRACKBACK . "</sioc:type>\n";
914                //        else $rdf .= "            <sioc:type>" . POST_COMMENT  . "</sioc:type>\n";
915                $rdf .= "            <rdfs:seeAlso rdf:resource=\"" . $exp->siocURL('comment', $id) . "\"/>\n";
916                $rdf .= "        </sioc:Post>\n";
917                $rdf .= "    </sioc:has_reply>\n";
918            }
919        }
920        $rdf .= "</" . $this->_type . ">\n";
921        return $rdf;
922    }
923}
924
925/**
926 * SIOC::WikiArticle object
927 *
928 * Contains information about a wiki article
929 */
930class SIOCWikiArticle extends SIOCObject
931{
932
933    private $type = 'sioct:WikiArticle';
934
935    private $url;
936    private $api = null;
937    private $subject;
938    private $redirpage;
939    private $creator;
940    private $created;
941    private $topics;
942    private $links;
943    private $ext_links;
944    private $previous_version;
945    private $next_version;
946    private $latest_version;
947    private $has_discussion;
948    private $has_container;
949
950    public function __construct(
951        $url,
952        $api,
953        $subject,
954        $redir,
955        $user,
956        $created,
957        $prev_vers,
958        $next_vers,
959        $latest_vers,
960        $has_discuss,
961        $container,
962        $topics = array(),
963        $links = array(),
964        $ext_links = array(),
965        $type = 'sioct:WikiArticle'
966    ) {
967        $this->url              = $url;
968        $this->api              = $api;
969        $this->subject          = $subject;
970        $this->redirpage        = $redir;
971        $this->creator          = $user;
972        $this->created          = $created;
973        $this->topics           = $topics;
974        $this->links            = $links;
975        $this->ext_links        = $ext_links;
976        $this->_type            = $type;
977        $this->previous_version = $prev_vers;
978        $this->next_version     = $next_vers;
979        $this->latest_version   = $latest_vers;
980        $this->has_discussion   = $has_discuss;
981        $this->has_container    = $container;
982    }
983
984    public function getContent(&$exp): string
985    {
986        $rdf = '<' . $this->_type . " rdf:about=\"" . clean($this->url) . "\">\n";
987        if ($this->subject) {
988            $rdf .= "    <dc:title>" . clean($this->subject) . "</dc:title>\n";
989            if (strcmp($this->has_container, 'http://en.wikipedia.org') === 0) {
990                $rdf .= "    <foaf:primaryTopic rdf:resource=\"" . clean(
991                        'http://dbpedia.org/resource/' . $this->subject
992                    ) . "\"/>\n";
993            }
994        }
995        if ($this->creator->_nick) {
996            /*if ($this->creator->id) {
997                $rdf .= "    <sioc:has_creator>\n";
998                $rdf .= "        <sioc:UserAccount rdf:about=\"" . clean($this->creator->uri) ."\">\n";
999                if($this->creator->sioc_url) { $rdf .= "    <rdfs:seeAlso rdf:resource=\"". $this->creator->sioc_url
1000                ."\"/>\n"; }
1001                else $rdf .= "            <rdfs:seeAlso rdf:resource=\"" . $exp->siocURL('user', $this->creator->id)
1002                        . "\"/>\n";
1003                $rdf .= "        </sioc:UserAccount>\n";
1004                $rdf .= "    </sioc:has_creator>\n";
1005                $rdf .= "    <foaf:maker>\n";
1006                $rdf .= "        <foaf:Person rdf:about=\"" . clean($this->creator->foaf_uri) ."\">\n";
1007                if($this->creator->foaf_url) { $rdf .= "    <rdfs:seeAlso rdf:resource=\"". $this->creator->foaf_url
1008                        ."\"/>\n"; }
1009                else $rdf .= "            <rdfs:seeAlso rdf:resource=\"" . $exp->siocURL('user', $this->creator->id)
1010                        . "\"/>\n";
1011                $rdf .= "        </foaf:Person>\n";
1012                $rdf .= "    </foaf:maker>\n";
1013            } else {*/
1014            $rdf .= "    <sioc:has_creator>\n";
1015            $rdf .= "        <sioc:UserAccount rdf:about=\"" . clean($this->creator->_uri) . "\">\n";
1016            $rdf .= "            <rdfs:seeAlso rdf:resource=\"" . clean(
1017                    'http://ws.sioc-project.org/mediawiki/mediawiki.php?wiki=' . $this->creator->_uri
1018                );
1019            if ($this->api) {
1020                $rdf .= clean("&api=" . $this->api);
1021            }
1022            $rdf .= "\"/>\n";
1023            $rdf .= "        </sioc:UserAccount>\n";
1024            $rdf .= "    </sioc:has_creator>\n";
1025            $rdf .= "    <dc:contributor>" . clean($this->creator->_nick) . "</dc:contributor>\n";
1026            /*$rdf .= "    <foaf:maker>\n";
1027            $rdf .= "        <foaf:Person";
1028            if($this->creator->name) $rdf .= " foaf:name=\"" . $this->creator->name ."\"";
1029            if($this->creator->sha1) $rdf .= " foaf:mbox_sha1sum=\"" . $this->creator->sha1 ."\"";
1030            if($this->creator->homepage) $rdf .= ">\n            <foaf:homepage rdf:resource=\""
1031            . $this->creator->homepage ."\"/>\n        </foaf:Person>\n";
1032            else $rdf .= "/>\n";
1033            $rdf .= "    </foaf:maker>\n";
1034        }*/
1035        } else {
1036            if ($this->creator !== 'void') {
1037                $rdf .= "    <sioc:has_creator>\n";
1038                $rdf .= "        <sioc:UserAccount>\n";
1039                $rdf .= "        </sioc:UserAccount>\n";
1040                $rdf .= "    </sioc:has_creator>\n";
1041            }
1042        }
1043        if ($this->created) {
1044            $rdf .= "    <dcterms:created>" . $this->created . "</dcterms:created>\n";
1045        }
1046        if (is_array($this->topics)) {
1047            foreach ($this->topics as $topic => $url) {
1048                $rdf .= "    <sioc:topic>\n";
1049                $rdf .= "        <sioct:Category rdf:about=\"" . clean($url) . "\">\n";
1050                $rdf .= "            <rdfs:seeAlso rdf:resource=\"" . clean(
1051                        'http://ws.sioc-project.org/mediawiki/mediawiki.php?wiki=' . $url
1052                    );
1053                if ($this->api) {
1054                    $rdf .= clean("&api=" . $this->api);
1055                }
1056                $rdf .= "\"/>\n";
1057                $rdf .= "        </sioct:Category>\n";
1058                $rdf .= "    </sioc:topic>\n";
1059            }
1060        }
1061        if (is_array($this->links)) {
1062            foreach ($this->links as $label => $url) {
1063                $rdf .= "    <sioc:links_to>\n";
1064                $rdf .= "        <sioct:WikiArticle rdf:about=\"" . clean($url) . "\">\n";
1065                $rdf .= "            <rdfs:seeAlso rdf:resource=\"" . clean(
1066                        'http://ws.sioc-project.org/mediawiki/mediawiki.php?wiki=' . $url
1067                    );
1068                if ($this->api) {
1069                    $rdf .= clean("&api=" . $this->api);
1070                }
1071                $rdf .= "\"/>\n";
1072                $rdf .= "        </sioct:WikiArticle>\n";
1073                $rdf .= "    </sioc:links_to>\n";
1074            }
1075        } else {
1076            if ($this->links) {
1077                $rdf .= "    <sioc:links_to>\n";
1078                $rdf .= "        <sioct:WikiArticle rdf:about=\"" . clean($this->links) . "\">\n";
1079                $rdf .= "            <rdfs:seeAlso rdf:resource=\"" . clean(
1080                        'http://ws.sioc-project.org/mediawiki/mediawiki.php?wiki=' . $this->links
1081                    );
1082                if ($this->api) {
1083                    $rdf .= clean("&api=" . $this->api);
1084                }
1085                $rdf .= "\"/>\n";
1086                $rdf .= "        </sioct:WikiArticle>\n";
1087                $rdf .= "    </sioc:links_to>\n";
1088            }
1089        }
1090        if (is_array($this->ext_links)) {
1091            foreach ($this->ext_links as $label => $url) {
1092                $rdf .= "    <sioc:links_to rdf:resource=\"" . clean($url) . "\"/>\n";
1093            }
1094        }
1095        if ($this->previous_version) {
1096            $rdf .= "    <sioc:previous_version>\n";
1097            $rdf .= "        <sioct:WikiArticle rdf:about=\"" . clean($this->previous_version) . "\">\n";
1098            $rdf .= "            <rdfs:seeAlso rdf:resource=\"" . clean(
1099                    'http://ws.sioc-project.org/mediawiki/mediawiki.php?wiki=' . $this->previous_version
1100                );
1101            if ($this->api) {
1102                $rdf .= clean("&api=" . $this->api);
1103            }
1104            $rdf .= "\"/>\n";
1105            $rdf .= "        </sioct:WikiArticle>\n";
1106            $rdf .= "    </sioc:previous_version>\n";
1107            /*If there is support for inference and transitivity the following is not needed
1108            $rdf .= "    <sioc:earlier_version>\n";
1109            $rdf .= "        <sioct:WikiArticle rdf:about=\"" . clean($this->previous_version) ."\">\n";
1110            $rdf .= "            <rdfs:seeAlso rdf:resource=\"" .
1111                    clean('http://ws.sioc-project.org/mediawiki/mediawiki.php?wiki='.$this->previous_version);
1112            if ($this->api) {
1113              $rdf .= clean("&api=" . $this->api);
1114            }
1115            $rdf .= "\"/>\n";
1116            $rdf .= "        </sioct:WikiArticle>\n";
1117            $rdf .= "    </sioc:earlier_version>\n";
1118             */
1119        }
1120        if ($this->next_version) {
1121            $rdf .= "    <sioc:next_version>\n";
1122            $rdf .= "        <sioct:WikiArticle rdf:about=\"" . clean($this->next_version) . "\">\n";
1123            $rdf .= "            <rdfs:seeAlso rdf:resource=\"" . clean(
1124                    'http://ws.sioc-project.org/mediawiki/mediawiki.php?wiki=' . $this->next_version
1125                );
1126            if ($this->api) {
1127                $rdf .= clean("&api=" . $this->api);
1128            }
1129            $rdf .= "\"/>\n";
1130            $rdf .= "        </sioct:WikiArticle>\n";
1131            $rdf .= "    </sioc:next_version>\n";
1132            /*If there is support for inference and transitivity the following is not needed
1133            $rdf .= "    <sioc:later_version>\n";
1134            $rdf .= "        <sioct:WikiArticle rdf:about=\"" . clean($this->next_version) ."\">\n";
1135            $rdf .= "            <rdfs:seeAlso rdf:resource=\"" .
1136                    clean('http://ws.sioc-project.org/mediawiki/mediawiki.php?wiki='.$this->next_version);
1137            if ($this->api) {
1138              $rdf .= clean("&api=" . $this->api);
1139            }
1140            $rdf .= "\"/>\n";
1141            $rdf .= "        </sioct:WikiArticle>\n";
1142            $rdf .= "    </sioc:later_version>\n";
1143             */
1144        }
1145        if ($this->latest_version) {
1146            $rdf .= "    <sioc:latest_version>\n";
1147            $rdf .= "        <sioct:WikiArticle rdf:about=\"" . clean($this->latest_version) . "\">\n";
1148            $rdf .= "            <rdfs:seeAlso rdf:resource=\"" . clean(
1149                    'http://ws.sioc-project.org/mediawiki/mediawiki.php?wiki=' . $this->latest_version
1150                );
1151            if ($this->api) {
1152                $rdf .= clean("&api=" . $this->api);
1153            }
1154            $rdf .= "\"/>\n";
1155            $rdf .= "        </sioct:WikiArticle>\n";
1156            $rdf .= "    </sioc:latest_version>\n";
1157        }
1158        if ($this->has_discussion && (strpos($this->has_discussion, 'Talk:Talk:') == false)) {
1159            $rdf .= "    <sioc:has_discussion>\n";
1160            $rdf .= "        <sioct:WikiArticle rdf:about=\"" . clean($this->has_discussion) . "\">\n";
1161            $rdf .= "            <rdfs:seeAlso rdf:resource=\"" . clean(
1162                    'http://ws.sioc-project.org/mediawiki/mediawiki.php?wiki=' . $this->has_discussion
1163                );
1164            if ($this->api) {
1165                $rdf .= clean("&api=" . $this->api);
1166            }
1167            $rdf .= "\"/>\n";
1168            $rdf .= "        </sioct:WikiArticle>\n";
1169            $rdf .= "    </sioc:has_discussion>\n";
1170        }
1171        if ($this->has_container) {
1172            $rdf .= "    <sioc:has_container>\n";
1173            $rdf .= "        <sioct:Wiki rdf:about=\"" . clean($this->has_container) . "\"/>\n";
1174            $rdf .= "    </sioc:has_container>\n";
1175        }
1176        if ($this->redirpage) {
1177            $rdf .= "    <owl:sameAs rdf:resource=\"" . clean($this->redirpage) . "\"/>\n";
1178            $rdf .= "    <rdfs:seeAlso rdf:resource=\"" . clean(
1179                    'http://ws.sioc-project.org/mediawiki/mediawiki.php?wiki=' . $this->redirpage
1180                );
1181            if ($this->api) {
1182                $rdf .= clean("&api=" . $this->api);
1183            }
1184            $rdf .= "\"/>\n";
1185        }
1186
1187        $rdf .= "</" . $this->_type . ">\n";
1188        return $rdf;
1189    }
1190}
1191
1192/**
1193 * SIOC::Wiki object
1194 *
1195 * Contains information about a wiki site
1196 */
1197class SIOCWiki extends SIOCObject
1198{
1199
1200    private $url;
1201    private $type;
1202
1203    public function __construct($url, $type = 'sioct:Wiki')
1204    {
1205        $this->url  = $url;
1206        $this->type = $type;
1207    }
1208
1209    public function getContent(&$exp): string
1210    {
1211        $rdf = '<' . $this->type . " rdf:about=\"" . clean($this->url) . "\"/>\n";
1212        return $rdf;
1213    }
1214}
1215
1216/**
1217 * SIOC::Category object
1218 *
1219 * Contains information about the category which is object of the sioc:topic property
1220 */
1221class SIOCCategory extends SIOCObject
1222{
1223
1224    private $url;
1225    private $type;
1226
1227    public function __construct($url, $type = 'sioct:Category')
1228    {
1229        $this->url  = $url;
1230        $this->type = $type;
1231    }
1232
1233    public function getContent(&$exp): string
1234    {
1235        $rdf = '<' . $this->type . " rdf:about=\"" . clean($this->url) . "\"/>\n";
1236        return $rdf;
1237    }
1238}
1239
1240/**
1241 * "Clean" text
1242 *
1243 * Transforms text so that it can be safely put into XML markup
1244 */
1245if (!function_exists('clean')) {
1246    function clean($text, $url = false)
1247    {
1248#    return htmlentities( $text );
1249#    return htmlentities2( $text );
1250        // double encoding is preventable now
1251        // $text = htmlspecialchars_decode($text, ENT_COMPAT);
1252        if ($url) {
1253            $text = str_replace('&amp;', '&', $text);
1254        }
1255        return htmlspecialchars($text, ENT_COMPAT, 'UTF-8');
1256    }
1257}
1258
1259/**
1260 * HTML Entities 2
1261 *
1262 * Same a HTMLEntities, but avoids double-encoding of entities
1263 */
1264if (!function_exists('htmlentities2')) {
1265    function htmlentities2($myHTML)
1266    {
1267        $translation_table          = get_html_translation_table(HTML_ENTITIES, ENT_QUOTES);
1268        $translation_table[chr(38)] = '&';
1269        return preg_replace(
1270            "/&(?![A-Za-z]{0,4}\w{2,3};|#[0-9]{2,3};)/",
1271            "&amp;",
1272            strtr($myHTML, $translation_table)
1273        );
1274        //return htmlentities(strtr(str_replace(' ', '%20', $myHTML), $translation_table));
1275    }
1276}
1277
1278/**
1279 * pureContent
1280 *
1281 * Prepares text-only representation of HTML content
1282 */
1283if (!function_exists('pureContent')) {
1284    function pureContent($content)
1285    {
1286        // Remove HTML tags
1287        // May add more cleanup code later, if validation errors are found
1288        return strip_tags($content);
1289    }
1290}
1291