root/trunk/wifidog-auth/wifidog/classes/Content/HTMLeditor/HTMLeditor.php @ 1088

Revision 1088, 21.9 KB (checked in by max-horvath, 7 years ago)

"2006-09-02 Max Horvath <max.horvath@…>

  • Installation script checks for PHP session extension (fixes #139)
  • Removed \"Call-time pass-by-reference has been deprecated\" warnings (fixes #239)
  • Revert changes of FCKeditor implementation (fixes #240)
  • Fix of FCKeditor implementation, now also supports FCKeditor 2.3+ (fixes #145)
  • Hotspots/Nodes? are sorted case-insensitive now (fixes #109)
  • Fix #141
  • templates/sites/index.tpl: fix wrong user count (fixes #236)
  • Added more trash mail services to the black list (fixes #149)"
  • Property svn:eol-style set to native
  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
Line 
1<?php
2
3/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
4
5// +-------------------------------------------------------------------+
6// | WiFiDog Authentication Server                                     |
7// | =============================                                     |
8// |                                                                   |
9// | The WiFiDog Authentication Server is part of the WiFiDog captive  |
10// | portal suite.                                                     |
11// +-------------------------------------------------------------------+
12// | PHP version 5 required.                                           |
13// +-------------------------------------------------------------------+
14// | Homepage:     http://www.wifidog.org/                             |
15// | Source Forge: http://sourceforge.net/projects/wifidog/            |
16// +-------------------------------------------------------------------+
17// | This program is free software; you can redistribute it and/or     |
18// | modify it under the terms of the GNU General Public License as    |
19// | published by the Free Software Foundation; either version 2 of    |
20// | the License, or (at your option) any later version.               |
21// |                                                                   |
22// | This program is distributed in the hope that it will be useful,   |
23// | but WITHOUT ANY WARRANTY; without even the implied warranty of    |
24// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the     |
25// | GNU General Public License for more details.                      |
26// |                                                                   |
27// | You should have received a copy of the GNU General Public License |
28// | along with this program; if not, contact:                         |
29// |                                                                   |
30// | Free Software Foundation           Voice:  +1-617-542-5942        |
31// | 59 Temple Place - Suite 330        Fax:    +1-617-542-2652        |
32// | Boston, MA  02111-1307,  USA       gnu@gnu.org                    |
33// |                                                                   |
34// +-------------------------------------------------------------------+
35
36/**
37 * @package    WiFiDogAuthServer
38 * @subpackage ContentClasses
39 * @author     Max Horvath <max.horvath@maxspot.de>
40 * @copyright  2005-2006 Max Horvath, maxspot GmbH
41 * @version    Subversion $Id$
42 * @link       http://www.wifidog.org/
43 * @todo       Add CSS styles for editors.
44 */
45
46/**
47 * Load required classes
48 */
49require_once('classes/Content/Langstring/Langstring.php');
50
51/**
52 * FCKeditor implementation
53 *
54 * @package    WiFiDogAuthServer
55 * @subpackage ContentClasses
56 * @author     Max Horvath <max.horvath@maxspot.de>
57 * @copyright  2005-2006 Max Horvath, maxspot GmbH
58 */
59class HTMLeditor extends Content
60{
61
62    /**
63     * HTML allowed to be used
64     */
65    const ALLOWED_HTML_TAGS = "<p><div><pre><address><h1><h2><h3><h4><h5><h6><br><b><strong><i><em><u><span><ol><ul><li><a><img><embed><table><tbody><thead><th><tr><td><hr>";
66
67    /**
68     * Defines if the FCKeditor library has been installed
69     *
70     * @var bool
71     * @access private
72     */
73    private $_FCKeditorAvailable = false;
74
75    /**
76     * Constructor.
77     *
78     * @param int $content_id ID of content.
79     *
80     * @return void
81     *
82     * @access protected
83     */
84    protected function __construct($content_id)
85    {
86        parent::__construct($content_id);
87
88        // Check FCKeditor support
89        if (Dependencies::check("FCKeditor")) {
90            // Define globals
91            global $db;
92
93            // Load FCKeditor class
94            require_once('lib/FCKeditor/fckeditor.php');
95
96            $this->mBd = &$db;
97
98            $this->_FCKeditorAvailable = true;
99        }
100    }
101
102    /**
103     * Return string in the language requested by the user.
104     *
105     * @return string UTF-8 string of content.
106     *
107     * @access private
108     */
109    private function getString()
110    {
111        // Init values
112        $_retval = null;
113        $_row = null;
114        $_useCache = false;
115        $_cachedData = null;
116
117        // Create new cache objects
118        $_cacheLanguage = new Cache('langstrings_' . $this->id . '_substring_' . substr(Locale::getCurrentLocale()->getId(), 0, 2) . '_string', $this->id);
119        $_cache = new Cache('langstrings_' . $this->id . '_substring__string', $this->id);
120
121        // Check if caching has been enabled.
122        if ($_cacheLanguage->isCachingEnabled) {
123            $_cachedData = $_cacheLanguage->getCachedData();
124
125            if ($_cachedData) {
126                // Return cached data.
127                $_useCache = true;
128                $_retval = $_cachedData;
129            } else {
130                // Language specific cached data has not been found.
131                // Try to get language independent cached data.
132                $_cachedData = $_cache->getCachedData();
133
134                if ($_cachedData) {
135                    // Return cached data.
136                    $_useCache = true;
137                    $_retval = $_cachedData;
138                }
139            }
140        }
141
142        if (!$_useCache) {
143            // Get string in the prefered language of the user
144            $_sql = "SELECT value, locales_id, \n";
145            $_sql .= Locale::getSqlCaseStringSelect(Locale::getCurrentLocale()->getId());
146            $_sql .= " as score FROM content_langstring_entries WHERE content_langstring_entries.langstrings_id = '{$this->id}' AND value!='' ORDER BY score LIMIT 1";
147            $this->mBd->execSqlUniqueRes($_sql, $_row, false);
148
149            if ($_row == null) {
150                // String has not been found
151                $_retval = "(Empty string)";
152            } else {
153                // String has been found
154                $_retval = $_row['value'];
155
156                // Check if caching has been enabled.
157                if ($_cache->isCachingEnabled) {
158                    // Save data into cache, because it wasn't saved into cache before.
159                    $_cache->saveCachedData($_retval);
160                }
161            }
162        }
163
164        return $_retval;
165    }
166
167    /**
168     * Adds the string associated with the locale.
169     *
170     * @param string $string             String to be added
171     * @param string $locale             Locale of string (i.e. 'fr_CA') - can
172     *                                   be NULL
173     * @param bool   $allow_empty_string Defines if string may be empty
174     *
175     * @return bool True if string has been added, otherwise false.
176     *
177     * @access private
178     */
179    private function addString($string, $locale, $allow_empty_string = false)
180    {
181        // Init values
182        $_retval = false;
183        $_id = 'NULL';
184        $_idSQL = $_id;
185
186        if ($locale) {
187            // Set locale of string
188            $_language = new Locale($locale);
189
190            $_id = $_language->GetId();
191            $_idSQL = "'" . $_id . "'";
192        }
193
194        if ($allow_empty_string || ($string != null && $string != '')) {
195            // Save string in database
196            $string = $this->mBd->escapeString($string);
197            $this->mBd->execSqlUpdate("INSERT INTO content_langstring_entries (langstring_entries_id, langstrings_id, locales_id, value) VALUES ('" . get_guid() . "', '$this->id', $_idSQL , '$string')", FALSE);
198
199            // Create new cache object.
200            $_cache = new Cache('langstrings_' . $this->id . '_substring_' .  $_id . '_string', $this->id);
201
202            // Check if caching has been enabled.
203            if ($_cache->isCachingEnabled) {
204                // Remove old cached data.
205                $_cache->eraseCachedData();
206
207                // Save data into cache.
208                $_cache->saveCachedData($string);
209            }
210
211            $_retval = true;
212        }
213
214        return $_retval;
215    }
216
217    /**
218     * Updates the string associated with the locale.
219     *
220     * @param string $string String to be updated.
221     * @param string $locale Locale of string (i.e. 'fr_CA') - can be NULL.
222     *
223     * @return bool True if string has been updated, otherwise false.
224     *
225     * @access private
226     */
227    private function UpdateString($string, $locale)
228    {
229        // Init values
230        $_retval = false;
231        $_id = 'NULL';
232        $_row = null;
233
234        if ($locale) {
235            // Set locale of string
236            $_language = new Locale($locale);
237
238            $_id = $_language->GetId();
239            $_idSQL = "'" . $_id . "'";
240        }
241
242        if ($string != null && $string != '') {
243            $string = $this->mBd->escapeString($string);
244
245            // If the update returns 0 (no update), try inserting the record
246            $this->mBd->execSqlUniqueRes("SELECT * FROM content_langstring_entries WHERE locales_id = $_idSQL AND langstrings_id = '$this->id'", $_row, false);
247
248            if ($_row != null) {
249                $this->mBd->execSqlUpdate("UPDATE content_langstring_entries SET value = '$string' WHERE langstrings_id = '$this->id' AND locales_id = $_idSQL", false);
250
251                // Create new cache object.
252                $_cache = new Cache('langstrings_' . $this->id . '_substring_' .  $_id . '_string', $this->id);
253
254                // Check if caching has been enabled.
255                if ($_cache->isCachingEnabled) {
256                    // Remove old cached data.
257                    $_cache->eraseCachedData();
258
259                    // Save data into cache.
260                    $_cache->saveCachedData($string);
261                }
262            } else {
263                $this->addString($string, $locale);
264            }
265
266            $_retval = true;
267        }
268        return $_retval;
269    }
270
271    /**
272     * Shows the administration interface for HTMLeditor.
273     *
274     * @param string $type_interface SIMPLE for a small HTML editor, LARGE
275     *                               for a larger HTML editor (default).
276     * @param int    $num_nouveau    Number of new HTML editors to be created.
277     *
278     * @return string HTML code for the administration interface.
279     *
280     * @access public
281     */
282    public function getAdminUI($type_interface = 'LARGE')
283    {
284        if ($this->_FCKeditorAvailable) {
285            // Init values
286            $_result = null;
287            $_html = '';
288            $_languages = new LocaleList();
289                        $_html .= "<ul class='admin_element_list'>\n";
290
291            $_html .= "<li class='admin_element_item_container content_html_editor'>\n";
292
293            $_html .= "<ul class='admin_element_list'>\n";
294
295            $_sql = "SELECT * FROM content_langstring_entries WHERE content_langstring_entries.langstrings_id = '$this->id' ORDER BY locales_id";
296            $this->mBd->execSql($_sql, $_result, FALSE);
297
298            // Show existing content
299            if ($_result != null) {
300                while (list($_key, $_value) = each($_result)) {
301                    $_html .= "<li class='admin_element_item_container'>\n";
302                    $_html .= "<div class='admin_element_data'>\n";
303                    $_html .= _("Language") . ": " . $_languages->GenererFormSelect($_value["locales_id"], "langstrings_" . $this->id . "_substring_" . $_value["langstring_entries_id"] . "_language", 'Langstring::AfficherInterfaceAdmin', TRUE);
304
305                    $_FCKeditor = new FCKeditor('langstrings_' . $this->id . '_substring_' . $_value["langstring_entries_id"] . '_string');
306                    $_FCKeditor->BasePath = SYSTEM_PATH . "lib/FCKeditor/";
307                    $_FCKeditor->Config["CustomConfigurationsPath"] = BASE_URL_PATH . "js/HTMLeditor.js";
308                    $_FCKeditor->Config["AutoDetectLanguage"] = false;
309                    $_FCKeditor->Config["DefaultLanguage"] = substr(Locale::getCurrentLocale()->getId(), 0, 2);
310                    $_FCKeditor->Config["StylesXmlPath"] = BASE_URL_PATH . "templates/HTMLeditor/css/" . substr(Locale::getCurrentLocale()->getId(), 0, 2) . ".xml";
311                    $_FCKeditor->Config["TemplatesXmlPath"] = BASE_URL_PATH . "templates/HTMLeditor/templates/" . substr(Locale::getCurrentLocale()->getId(), 0, 2) . ".xml";
312
313                    $_FCKeditor->ToolbarSet = "WiFiDOG";
314
315                    $_FCKeditor->Value = $_value['value'];
316
317                    if ($type_interface == 'LARGE') {
318                        $_FCKeditor->Height = 400;
319                    } else {
320                        $_FCKeditor->Height = 200;
321                    }
322                    $_FCKeditor->Width = 386;
323
324                    $_html .= $_FCKeditor->CreateHtml();
325
326                    $_html .= "</div>\n";
327                    $_html .= "<div class='admin_element_tools'>\n";
328
329                    $_name = "langstrings_" . $this->id . "_substring_" . $_value["langstring_entries_id"] . "_erase";
330                    $_html .= "<input type='submit' class='submit' name='$_name' value='" . _("Delete string") . "'>";
331
332                    $_html .= "</div>\n";
333                    $_html .= "</li>\n";
334                }
335            }
336
337            // Editor for new content
338            $_locale = LocaleList::GetDefault();
339
340            $_html .= "<li class='admin_element_item_container'>\n";
341            $_html .= "<div class='admin_element_data'>\n";
342
343            $_html .= _("Language") . ": " . $_languages->GenererFormSelect($_locale, "langstrings_" . $this->id . "_substring_new_language", 'Langstring::AfficherInterfaceAdmin', TRUE);
344
345            $_FCKeditor = new FCKeditor('langstrings_' . $this->id . '_substring_new_string');
346            $_FCKeditor->BasePath = SYSTEM_PATH . "lib/FCKeditor/";
347            $_FCKeditor->Config["CustomConfigurationsPath"] = BASE_URL_PATH . "js/HTMLeditor.js";
348            $_FCKeditor->Config["AutoDetectLanguage"] = false;
349            $_FCKeditor->Config["DefaultLanguage"] = substr(Locale::getCurrentLocale()->getId(), 0, 2);
350            $_FCKeditor->Config["StylesXmlPath"] = BASE_URL_PATH . "templates/HTMLeditor/css/" . substr(Locale::getCurrentLocale()->getId(), 0, 2) . ".xml";
351            $_FCKeditor->Config["TemplatesXmlPath"] = BASE_URL_PATH . "templates/HTMLeditor/templates/" . substr(Locale::getCurrentLocale()->getId(), 0, 2) . ".xml";
352            $_FCKeditor->ToolbarSet = "WiFiDOG";
353
354            $_FCKeditor->Value = "";
355
356            if ($type_interface == 'LARGE') {
357                $_FCKeditor->Height = 400;
358            } else {
359                $_FCKeditor->Height = 200;
360            }
361            $_FCKeditor->Width = 386;
362
363            $_html .= $_FCKeditor->CreateHtml();
364
365            $_html .= "</div>\n";
366            $_html .= "<div class='admin_element_tools'>\n";
367
368            $_html .= "<input type='submit' class='submit' name='langstrings_" . $this->id . "_add_new_entry' value='" . _("Add new string") . "'>";
369            $_html .= "</div>\n";
370            $_html .= "</li>\n";
371
372            $_html .= "</ul>\n";
373            $_html .= "</li>\n";
374            $_html .= "</ul>\n";
375        } else {
376            $_html = '';
377            $_html .= _("FCKeditor is not installed");
378        }
379
380        return parent :: getAdminUI($_html);
381    }
382
383    /**
384     * Processes the input of the administration interface for HTMLeditor
385     *
386     * @return void
387     *
388     * @access public
389     */
390    public function processAdminUI()
391    {
392        // Check FCKeditor support
393        if ($this->_FCKeditorAvailable) {
394            // Init values
395            $_result = null;
396
397            if ($this->isOwner(User::getCurrentUser()) || User::getCurrentUser()->isSuperAdmin()) {
398                parent::processAdminUI();
399
400                $_form_select = new FormSelectGenerator();
401
402                $_sql = "SELECT * FROM content_langstring_entries WHERE content_langstring_entries.langstrings_id = '$this->id'";
403                $this->mBd->execSql($_sql, $_result, FALSE);
404
405                if ($_result != null) {
406                    while (list($_key, $_value) = each($_result)) {
407                        $_language = $_form_select->getResult("langstrings_" . $this->id . "_substring_" . $_value["langstring_entries_id"] . "_language", 'Langstring::AfficherInterfaceAdmin');
408
409                        if (empty ($_language)) {
410                            $_language = '';
411                            $_languageSQL = 'NULL';
412                        } else {
413                            $_languageSQL = "'" . $_language . "'";
414                        }
415
416                        if (!empty ($_REQUEST["langstrings_" . $this->id . "_substring_" . $_value["langstring_entries_id"] . "_erase"]) && $_REQUEST["langstrings_" . $this->id . "_substring_" . $_value["langstring_entries_id"] . "_erase"] == true) {
417                            $this->mBd->execSqlUpdate("DELETE FROM content_langstring_entries WHERE langstrings_id = '$this->id' AND langstring_entries_id='" . $_value["langstring_entries_id"] . "'", FALSE);
418
419                            // Create new cache object.
420                            $_cache = new Cache('langstrings_' . $this->id . '_substring_' .  $_language . '_string', $this->id);
421
422                            // Check if caching has been enabled.
423                            if ($_cache->isCachingEnabled) {
424                                // Remove old cached data.
425                                $_cache->eraseCachedData();
426                            }
427                        } else {
428                            // Strip HTML tags!
429                            $string = $_REQUEST["langstrings_" . $this->id . "_substring_" . $_value["langstring_entries_id"] . "_string"];
430                            $string = $this->mBd->escapeString(strip_tags($string, self::ALLOWED_HTML_TAGS));
431
432                            // If PEAR::HTML_Safe is available strips down all potentially dangerous content
433                            $_HtmlSafe = new HtmlSafe();
434
435                            if ($_HtmlSafe->isHtmlSafeEnabled) {
436                                $string = $_HtmlSafe->parseHtml($string);
437                            }
438
439                            $this->mBd->execSqlUpdate("UPDATE content_langstring_entries SET locales_id = " . $_languageSQL . " , value = '$string' WHERE langstrings_id = '$this->id' AND langstring_entries_id='" . $_value["langstring_entries_id"] . "'", FALSE);
440
441                            // Create new cache object.
442                            $_cache = new Cache('langstrings_' . $this->id . '_substring_' .  $_language . '_string', $this->id);
443
444                            // Check if caching has been enabled.
445                            if ($_cache->isCachingEnabled) {
446                                // Remove old cached data.
447                                $_cache->eraseCachedData();
448
449                                // Save data into cache.
450                                $_cache->saveCachedData($string);
451                            }
452                        }
453                    }
454                }
455
456                $_new_substring_name = "langstrings_" . $this->id . "_substring_new_string";
457                $_new_substring_submit_name = "langstrings_" . $this->id . "_add_new_entry";
458                if ((isset ($_REQUEST[$_new_substring_submit_name]) && $_REQUEST[$_new_substring_submit_name] == true) || !empty ($_REQUEST[$_new_substring_name])) {
459                    $_language = $_form_select->getResult("langstrings_" . $this->id . "_substring_new_language", 'Langstring::AfficherInterfaceAdmin');
460
461                    if (empty($_language)) {
462                        $_language = null;
463                    }
464
465                    $this->addString($_REQUEST[$_new_substring_name], $_language, true);
466                }
467            }
468        }
469    }
470
471    /**
472     * Retreives the user interface of this object. Anything that overrides
473     * this method should call the parent method with it's output at the
474     * END of processing.
475     *
476     * @param string $subclass_admin_interface HTML content of the interface
477     *                                         element of a children.
478     *
479     * @return string The HTML fragment for this interface.
480     *
481     * @access public
482     */
483    public function getUserUI($subclass_user_interface = null)
484    {
485        // Init values
486        $_html = "";
487
488        $_html .= "<div class='user_ui_container ".get_class($this)."'>\n";
489        $_html .= "<div class='langstring'>\n";
490
491        // Check FCKeditor support
492        if ($this->_FCKeditorAvailable) {
493            $_html .= $this->getString();
494        } else {
495            $_html .= _("FCKeditor is not installed");
496        }
497
498        $_html .= $subclass_user_interface;
499        $_html .= "</div>\n";
500        $_html .= "</div>\n";
501
502        return parent::getUserUI($_html);
503    }
504
505    /**
506     * Reloads the object from the database. Should normally be called after
507     * a set operation. This function is private because calling it from a
508     * subclass will call the constructor from the wrong scope.
509     *
510     * @return void
511     *
512     * @access private
513     */
514    private function refresh()
515    {
516        $this->__construct($this->id);
517    }
518
519    /**
520     * Deletes a HTMLeditor object
521     *
522     * @param string $errmsg Reference to error message
523     *
524     * @return bool True if deletion was successful
525     *
526     * @access public
527     * @internal Persistent content will not be deleted
528     */
529    public function delete(& $errmsg) {
530        // Init values.
531        $_retval = false;
532
533        if ($this->isPersistent()) {
534            $errmsg = _("Content is persistent (you must make it non persistent before you can delete it)");
535        } else {
536            global $db;
537
538            if ($this->isOwner(User::getCurrentUser()) || User::getCurrentUser()->isSuperAdmin()) {
539                $_sql = "DELETE FROM content WHERE content_id='$this->id'";
540                $db->execSqlUpdate($_sql, false);
541                $_retval = true;
542
543                // Create new cache object.
544                $_cache = new Cache('all', $this->id);
545
546                // Check if caching has been enabled.
547                if ($_cache->isCachingEnabled) {
548                    // Remove old cached data.
549                    $_cache->eraseCachedGroupData();
550                }
551            } else {
552                $errmsg = _("Access denied (not owner of content)");
553            }
554        }
555
556        return $_retval;
557    }
558
559}
560
561/*
562 * Local variables:
563 * tab-width: 4
564 * c-basic-offset: 4
565 * c-hanging-comment-ender-p: nil
566 * End:
567 */
Note: See TracBrowser for help on using the browser.