root/trunk/wifidog-auth/wifidog/classes/Node.php @ 1088

Revision 1088, 50.8 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 * @author     Benoit Grégoire <bock@step.polymtl.ca>
39 * @copyright  2005-2006 Benoit Grégoire, Technologies Coeus inc.
40 * @version    Subversion $Id$
41 * @link       http://www.wifidog.org/
42 */
43
44/**
45 * Load required classes
46 */
47require_once('classes/User.php');
48require_once('classes/GisPoint.php');
49require_once('classes/AbstractGeocoder.php');
50require_once('classes/Utils.php');
51require_once('classes/DateTime.php');
52require_once('classes/InterfaceElements.php');
53
54/**
55 * Abstract a Node.  A Node is an actual physical transmitter.
56 *
57 * @todo Make all the setter functions no-op if the value is the same as what
58 * was already stored Use setCustomPortalReduirectUrl as an example
59 *
60 * @package    WiFiDogAuthServer
61 * @author     Benoit Grégoire <bock@step.polymtl.ca>
62 * @copyright  2005 Benoit Grégoire, Technologies Coeus inc.
63 */
64class Node implements GenericObject
65{
66        private $mRow;
67        private $mdB; /**< An AbstractDb instance */
68        private $id;
69        private static $current_node_id = null;
70
71        /**
72         * Defines a warning message
73         *
74         * @var string
75         *
76         * @access private
77         */
78        private $_warningMessage;
79
80        /** Instantiate a node object
81         * @param $id The id of the requested node
82         * @return a Node object, or null if there was an error
83         */
84        static function getObject($id)
85        {
86                $object = null;
87                $object = new self($id);
88                return $object;
89        }
90
91        /** Get the current node for which the portal is displayed or to which a user is physically connected.
92         * @param $real_node_only true or false.  If true, the real physical node where the user is connected is returned, and the node set by setCurrentNode is ignored.
93         * @return a Node object, or null if it can't be found.
94         */
95        static function getCurrentNode($real_node_only = false)
96        {
97                $object = null;
98                if (self :: $current_node_id != null && $real_node_only == false)
99                {
100                        $object = new self(self :: $current_node_id);
101                }
102                else
103                {
104                        $object = self :: getCurrentRealNode();
105                }
106                return $object;
107        }
108
109        /** Set the current node where the user is to be considered connected to.  (For portal and content display purpuses, among other.
110         * @param $node Node.  The new current node.
111         * @return true  */
112        static function setCurrentNode(Node $node)
113        {
114                self :: $current_node_id = $node->GetId();
115                return true;
116        }
117
118        /** Get the current node to which a user is physically connected, if any.  This is done by an IP adress lookup against the last reported IP adress of the node
119         * @param        * @return a Node object, or null if it can't be found.
120         */
121        public static function getCurrentRealNode()
122        {
123                global $db;
124                $retval = null;
125                $sql = "SELECT node_id, last_heartbeat_ip from nodes WHERE last_heartbeat_ip='$_SERVER[REMOTE_ADDR]' ORDER BY last_heartbeat_timestamp DESC";
126                $node_rows = null;
127                $db->execSql($sql, $node_rows, false);
128                $num_match = count($node_rows);
129                if ($num_match == 0)
130                {
131
132                        // User is not physically connected to a node
133                        $retval = null;
134                }
135                else
136                        if ($num_match = 1)
137                        {
138                                // Only a single node matches, the user is presumed to be there
139                                $retval = new self($node_rows[0]['node_id']);
140                        }
141                        else
142                        {
143                                /* We have more than one node matching the IP (the nodes are behind the same NAT).
144                                 * We will try to discriminate by finding which node the user last authenticated against.
145                                 * If the IP matches, we can be pretty certain the user is there.
146                                 */
147                                $retval = null;
148                                $current_user = User :: getCurrentUser();
149                                if ($current_user != null)
150                                {
151                                        $current_user_id = $current_user->getId();
152                                        $_SERVER['REMOTE_ADDR'];
153                                        $sql = "SELECT node_id, last_heartbeat_ip from connections NATURAL JOIN nodes WHERE user_id='$current_user_id' ORDER BY last_updated DESC ";
154                                        $db->execSql($sql, $node_rows, false);
155                                        $node_row = $node_rows[0];
156                                        if ($node_row != null && $node_row['last_heartbeat_ip'] == $_SERVER['REMOTE_ADDR'])
157                                        {
158                                                $retval = new self($node_row['node_id']);
159                                        }
160                                }
161                        }
162                return $retval;
163        }
164
165        public function delete(& $errmsg)
166        {
167                $retval = false;
168                $user = User :: getCurrentUser();
169                if ($user->isSuperAdmin()) {
170                        global $db;
171                        $id = $db->escapeString($this->getId());
172                        if (!$db->execSqlUpdate("DELETE FROM nodes WHERE node_id='{$id}'", false))
173                        {
174                                $errmsg = _('Could not delete node!');
175                        }
176                        else
177                        {
178                                $retval = true;
179                        }
180                }
181                else
182                {
183                        $errmsg = _('Access denied!');
184                }
185
186                return $retval;
187        }
188
189        /** Create a new Node in the database
190         * @param $node_id The id to be given to the new node.  If not present, a
191         * guid will be assigned.
192         * @param $network Network object.  The node's network.  If not present,
193         * the current Network will be assigned
194         *
195         * @return the newly created Node object, or null if there was an error
196         */
197        static function createNewObject($node_id = null, $network = null)
198        {
199                global $db;
200                if (empty ($node_id))
201                {
202                        $node_id = get_guid();
203                }
204                $node_id = $db->escapeString($node_id);
205
206                if (empty ($network))
207                {
208                        $network = Network :: getCurrentNetwork();
209                }
210                $network_id = $db->escapeString($network->getId());
211
212                $node_deployment_status = $db->escapeString("IN_PLANNING");
213                $node_name = _("New node");
214                if (Node :: nodeExists($node_id))
215                        throw new Exception(_('This node already exists.'));
216
217                $sql = "INSERT INTO nodes (node_id, network_id, creation_date, node_deployment_status, name) VALUES ('$node_id', '$network_id', NOW(),'$node_deployment_status', '$node_name')";
218
219                if (!$db->execSqlUpdate($sql, false))
220                {
221                        throw new Exception(_('Unable to insert new node into database!'));
222                }
223                $object = new self($node_id);
224                return $object;
225        }
226
227        /** Get an interface to pick a node.
228        * @param $user_prefix A identifier provided by the programmer to recognise it's generated html form
229        * @param $sql_additional_where Addidional where conditions to restrict the candidate objects
230        * @return html markup
231        */
232        public static function getSelectNodeUI($user_prefix, $sql_additional_where = null,$type_interface = "select")
233        {
234                global $db;
235                $html = '';
236                $name = "{$user_prefix}";
237                $sql = "SELECT node_id, name, node_deployment_status, is_splash_only_node from nodes WHERE 1=1 $sql_additional_where ORDER BY lower(node_id)";
238                $node_rows = null;
239                $db->execSql($sql, $node_rows, false);
240                if ($node_rows != null)
241                {
242                        Utils :: natsort2d($node_rows, "node_id");
243                        if ($type_interface != "table") {
244                                $html .= _("Node");
245                                $html .=  ": ";
246                                // Naturally-sorting by node_id
247                                $i = 0;
248                                foreach ($node_rows as $node_row)
249                                {
250                                        $tab[$i][0] = $node_row['node_id'];
251                                        $tab[$i][1] = $node_row['node_id'].": ".$node_row['name'];
252                                        $i ++;
253                                }
254                                $html .= FormSelectGenerator :: generateFromArray($tab, null, $name, null, false);
255                        } else {
256                                $html .= "<fieldset>\n\t<legend>Node List</legend>\n";
257                                $html .= "\t<span class='node_admin'>"._("Filter:")."<input type=\"text\" tabindex=\"1\" maxlength=\"40\" size=\"40\" id=\"nodes_list_filter\" name=\"nodes_list_filter\" /></span>\n\t<br/>\n";
258                                $html .= "\t<!--[if IE]><style type='text/css'>#node_list_div table.scrollable>tbody { height: 15px; }</style><![endif]-->\n";
259                                $html .= "\t<script src='" . BASE_URL_PATH . "js/filtertable.js' type='text/javascript' language='javascript' charset='utf-8'></script>\n";
260                                $html .= "\t<script src='" . BASE_URL_PATH . "js/sorttable.js' type='text/javascript' language='javascript' charset='utf-8'></script>\n";
261                                $html .= "\t<div id='node_list_div' class='node_admin tableContainer'>\n";
262                                $html .= "\t\t<table id='nodes_list' class='node_admin filterable scrollable sortable'>\n\n";
263                                $html .= "\t\t\t<thead class='fixedHeader'>\n\t\t\t\t<tr class='nofilter'>\n\t\t\t\t\t<th>Node Name</th>\n\t\t\t\t\t<th>Node ID</th>\n\t\t\t\t\t<th>Deployment Status</th>\n\t\t\t\t</tr>\n\t\t\t</thead>\n\t\t\t<tbody>";
264
265                                $i = 0;
266                                foreach ($node_rows as $node_row)
267                                {
268                                        $href = GENERIC_OBJECT_ADMIN_ABS_HREF."?object_id={$node_row['node_id']}&object_class=Node&action=edit";
269                                        $html .= "\t\t\t\t<tr class='row' onclick=\"javascript:location.href='{$href}'\">\n\t\t\t\t\t<td>{$node_row['name']}<noscript>(<a href='{$href}'>edit</a>)</noscript></td>\n\t\t\t\t\t<td>{$node_row['node_id']}</td>\n\t\t\t\t\t<td>{$node_row['node_deployment_status']}</td>\n\t\t\t\t</tr>\n";
270                                }
271                                $html .= "\t\t\t</tbody>\n\t\t</table>\n";
272                                $html .= "\t</div>\n";
273                                $html .= "</fieldset>\n";
274
275                        }
276                } else {
277                        $html .= "<div class='warningmsg'>"._("Sorry, no nodes available in the database")."</div>\n";
278                }
279                return $html;
280        }
281
282
283        /** Get the selected Network object.
284         * @param $user_prefix A identifier provided by the programmer to recognise it's generated form
285         * @return the node object
286         */
287        static function processSelectNodeUI($user_prefix)
288        {
289                $object = null;
290                $name = "{$user_prefix}";
291                return new self($_REQUEST[$name]);
292        }
293
294        /** Get an interface to create a new node.
295        * @param $network Optional:  The network to which the new node will belong,
296        * if absent, the user will be prompted.
297        * @return html markup
298        */
299        public static function getCreateNewObjectUI($network = null)
300        {
301                $html = '';
302                $html .= _("Add a new node with ID")." \n";
303                $name = "new_node_id";
304                $html .= "<input type='text' size='10' name='{$name}'>\n";
305                if ($network)
306                {
307                        $name = "new_node_network_id";
308                        $html .= "<input type='hidden' name='{$name}' value='{$network->getId()}'>\n";
309                }
310                else
311                {
312                        $html .= " "._("in ")." \n";
313                        $html .= Network :: getSelectNetworkUI('new_node');
314                }
315                return $html;
316
317        }
318
319        /** Process the new object interface.
320         *  Will return the new object if the user has the credentials and the form was fully filled.
321         * @return the node object or null if no new node was created.
322         */
323        static function processCreateNewObjectUI()
324        {
325                $retval = null;
326                $name = "new_node_id";
327                if (!empty ($_REQUEST[$name]))
328                {
329                        $node_id = $_REQUEST[$name];
330                        $name = "new_node_network_id";
331                        if (!empty ($_REQUEST[$name]))
332                        {
333                                $network = Network :: getObject($_REQUEST[$name]);
334                        }
335                        else
336                        {
337                                $network = Network :: processSelectNetworkUI('new_node');
338                        }
339                        if ($node_id && $network)
340                        {
341                                if (!$network->hasAdminAccess(User :: getCurrentUser()))
342                                {
343                                        throw new Exception(_("Access denied"));
344                                }
345                                $retval = self :: createNewObject($node_id, $network);
346                        }
347                }
348                return $retval;
349        }
350
351    /**
352     * Get an interface to select the deployment status
353     *
354     * @param string $user_prefix A identifier provided by the programmer to
355     *                            recognise it's generated html form
356     *
357     * @return string HTML markup
358     *
359     * @access public
360     */
361        public function getSelectDeploymentStatus($user_prefix)
362        {
363            // Define globals
364                global $db;
365
366                // Init values
367                $html = "";
368                $status_list = null;
369                $tab = array();
370
371                $name = "{$user_prefix}";
372                $db->execSql("SELECT node_deployment_status FROM node_deployment_status", $status_list, false);
373
374                if ($status_list == null) {
375                        throw new Exception(_("No deployment statuses could be found in the database"));
376                }
377
378                foreach ($status_list as $status) {
379                        $tab[] = array($status['node_deployment_status'], $status['node_deployment_status']);
380                }
381
382                $html .= FormSelectGenerator::generateFromArray($tab, $this->getDeploymentStatus(), $name, null, false);
383
384                return $html;
385        }
386
387        /** Get the selected deployment status
388         * @param $user_prefix A identifier provided by the programmer to recognise it's generated form
389         * @return the deployment status
390         */
391        public function processSelectDeploymentStatus($user_prefix)
392        {
393                $object = null;
394                $name = "{$user_prefix}";
395                return $_REQUEST[$name];
396        }
397
398        /** @param $node_id The id of the node */
399        private function __construct($node_id)
400        {
401                global $db;
402                $this->mDb = & $db;
403
404                $node_id_str = $db->escapeString($node_id);
405                $sql = "SELECT * FROM nodes WHERE node_id='$node_id_str'";
406                $row = null;
407                $db->execSqlUniqueRes($sql, $row, false);
408                if ($row == null)
409                {
410                        throw new Exception(sprintf(_("The node %s could not be found in the database!"), $node_id_str));
411                }
412                $this->mRow = $row;
413                $this->id = $row['node_id'];
414        }
415
416        function getId()
417        {
418                return $this->id;
419        }
420
421        /** Changing the id of a Node is supported.
422         *  Be carefull to anly call this when all other changes are processed,
423         * or the id used to generate the form names may no longer match.
424         * @param $id, string, the new node id.
425         * @return true on success, false on failure. Check this,
426         * as it's possible that someone will enter an existing id, especially
427         * if the MAC address is used and hardware is recycled.
428         */
429        function setId($id)
430        {
431                $id = $this->mDb->escapeString($id);
432                $retval = $this->mDb->execSqlUpdate("UPDATE nodes SET node_id = '{$id}' WHERE node_id = '{$this->getId()}'");
433                if ($retval)
434                {
435                        $this->id = $id;
436                        $this->refresh();
437                }
438                return $retval;
439        }
440
441        /** Gets the Network to which the node belongs
442         * @return Network object (never returns null)
443         */
444        public function getNetwork()
445        {
446                return Network :: getObject($this->mRow['network_id']);
447        }
448
449        /** Get a GisPoint object ; altide is not supported yet
450         */
451        function getGisLocation()
452        {
453                // Altitude is not supported yet
454                return new GisPoint($this->mRow['latitude'], $this->mRow['longitude'], 0);
455        }
456
457        function setGisLocation($pt)
458        {
459                if (!empty ($pt))
460                {
461                        $lat = $this->mDb->escapeString($pt->getLatitude());
462                        $long = $this->mDb->escapeString($pt->getLongitude());
463
464                        if (!empty ($lat) && !empty ($long))
465                                $this->mDb->execSqlUpdate("UPDATE nodes SET latitude = $lat, longitude = $long WHERE node_id = '{$this->getId()}'");
466                        else
467                                $this->mDb->execSqlUpdate("UPDATE nodes SET latitude = NULL, longitude = NULL WHERE node_id = '{$this->getId()}'");
468                        $this->refresh();
469                }
470        }
471
472        /** Return the name of the node
473         */
474        function getName()
475        {
476                return $this->mRow['name'];
477        }
478
479        function setName($name)
480        {
481                $name = $this->mDb->escapeString($name);
482                $this->mDb->execSqlUpdate("UPDATE nodes SET name = '{$name}' WHERE node_id = '{$this->getId()}'");
483                $this->refresh();
484        }
485
486        function getCreationDate()
487        {
488                return $this->mRow['creation_date'];
489        }
490
491        function setCreationDate($creation_date)
492        {
493                $creation_date = $this->mDb->escapeString($creation_date);
494                $this->mDb->execSqlUpdate("UPDATE nodes SET creation_date = '{$creation_date}' WHERE node_id = '{$this->getId()}'");
495                $this->refresh();
496        }
497
498        function getHomePageURL()
499        {
500                return $this->mRow['home_page_url'];
501        }
502
503        function setHomePageUrl($url)
504        {
505                $url = $this->mDb->escapeString($url);
506                $this->mDb->execSqlUpdate("UPDATE nodes SET home_page_url = '{$url}' WHERE node_id = '{$this->getId()}'");
507                $this->refresh();
508        }
509
510        function getDescription()
511        {
512                return $this->mRow['description'];
513        }
514
515        function setDescription($description)
516        {
517                $description = $this->mDb->escapeString($description);
518                $this->mDb->execSqlUpdate("UPDATE nodes SET description = '{$description}' WHERE node_id = '{$this->getId()}'");
519                $this->refresh();
520        }
521
522        function getMapURL()
523        {
524                return $this->mRow['map_url'];
525        }
526
527        function setMapURL($url)
528        {
529                $url = $this->mDb->escapeString($url);
530                $this->mDb->execSqlUpdate("UPDATE nodes SET map_url = '{$url}' WHERE node_id = '{$this->getId()}'");
531                $this->refresh();
532        }
533
534        public function getCivicNumber()
535        {
536                return $this->mRow['civic_number'];
537        }
538
539        public function setCivicNumber($civic_number)
540        {
541                $civic_number = $this->mDb->escapeString($civic_number);
542                $this->mDb->execSqlUpdate("UPDATE nodes SET civic_number = '{$civic_number}' WHERE node_id = '{$this->getId()}'");
543                $this->refresh();
544        }
545
546        public function getStreetName()
547        {
548                return $this->mRow['street_name'];
549        }
550
551        public function setStreetName($street_name)
552        {
553                $street_name = $this->mDb->escapeString($street_name);
554                $this->mDb->execSqlUpdate("UPDATE nodes SET street_name = '{$street_name}' WHERE node_id = '{$this->getId()}'");
555                $this->refresh();
556        }
557
558        public function getCity()
559        {
560                return $this->mRow['city'];
561        }
562
563        public function setCity($city)
564        {
565                $city = $this->mDb->escapeString($city);
566                $this->mDb->execSqlUpdate("UPDATE nodes SET city = '{$city}' WHERE node_id = '{$this->getId()}'");
567                $this->refresh();
568        }
569
570        public function getProvince()
571        {
572                return $this->mRow['province'];
573        }
574
575        public function setProvince($province)
576        {
577                $province = $this->mDb->escapeString($province);
578                $this->mDb->execSqlUpdate("UPDATE nodes SET province = '{$province}' WHERE node_id = '{$this->getId()}'");
579                $this->refresh();
580        }
581
582        public function getCountry()
583        {
584                return $this->mRow['country'];
585        }
586
587        protected function setCountry($country)
588        {
589                $country = $this->mDb->escapeString($country);
590                $this->mDb->execSqlUpdate("UPDATE nodes SET country = '{$country}' WHERE node_id = '{$this->getId()}'");
591                $this->refresh();
592        }
593
594        public function getPostalCode()
595        {
596                return $this->mRow['postal_code'];
597        }
598
599        public function setPostalCode($postal_code)
600        {
601                $postal_code = $this->mDb->escapeString($postal_code);
602                $this->mDb->execSqlUpdate("UPDATE nodes SET postal_code = '{$postal_code}' WHERE node_id = '{$this->getId()}'");
603                $this->refresh();
604        }
605
606        function getTelephone()
607        {
608                return $this->mRow['public_phone_number'];
609        }
610
611        function setTelephone($phone)
612        {
613                $phone = $this->mDb->escapeString($phone);
614                $this->mDb->execSqlUpdate("UPDATE nodes SET public_phone_number = '{$phone}' WHERE node_id = '{$this->getId()}'");
615                $this->refresh();
616        }
617
618        function getTransitInfo()
619        {
620                return $this->mRow['mass_transit_info'];
621        }
622
623        function setTransitInfo($transit_info)
624        {
625                $transit_info = $this->mDb->escapeString($transit_info);
626                $this->mDb->execSqlUpdate("UPDATE nodes SET mass_transit_info = '{$transit_info}' WHERE node_id = '{$this->getId()}'");
627                $this->refresh();
628        }
629
630        function getEmail()
631        {
632                return $this->mRow['public_email'];
633        }
634
635        function setEmail($email)
636        {
637                $email = $this->mDb->escapeString($email);
638                $this->mDb->execSqlUpdate("UPDATE nodes SET public_email = '{$email}' WHERE node_id = '{$this->getId()}'");
639                $this->refresh();
640        }
641
642        function getDeploymentStatus()
643        {
644                return $this->mRow['node_deployment_status'];
645        }
646
647        function setDeploymentStatus($status)
648        {
649                $status = $this->mDb->escapeString($status);
650                $this->mDb->execSqlUpdate("UPDATE nodes SET node_deployment_status = '{$status}' WHERE node_id = '{$this->getId()}'");
651                $this->refresh();
652        }
653
654        function getLastPaged()
655        {
656                return $this->mRow['last_paged'];
657        }
658
659        function setLastPaged($last_paged)
660        {
661                $this->mDb->execSqlUpdate("UPDATE nodes SET last_paged = {$last_paged}::abstime WHERE node_id = '{$this->getId()}'");
662                $this->refresh();
663        }
664
665        function getLastHeartbeatIP()
666        {
667                return $this->mRow['last_heartbeat_ip'];
668        }
669
670        function getLastHeartbeatUserAgent()
671        {
672                return $this->mRow['last_heartbeat_user_agent'];
673        }
674
675        function getLastHeartbeatTimestamp()
676        {
677                return $this->mRow['last_heartbeat_timestamp'];
678        }
679
680        function setLastHeartbeatTimestamp($timestamp)
681        {
682                $this->mDb->execSqlUpdate("UPDATE nodes SET last_heartbeat_timestamp = '{$timestamp}' WHERE node_id = '{$this->getId()}'");
683                $this->refresh();
684        }
685
686        /** Is the node a Splash Only node?  Will only return true if the Network configuration allows it.
687         * @return true or false */
688        public function isSplashOnly()
689        {
690                return $this->getNetwork()->getSplashOnlyNodesAllowed() && $this->isConfiguredSplashOnly();
691        }
692
693        /** Is the node configured as a Splash Only node?  This is NOT the same as isSplashOnly().
694         * This is the getter for the configuration set in the database for this node.
695         * For the node to actually be splash only, this AND the network
696         * gonfiguration must match.
697         * @return true or false */
698        public function isConfiguredSplashOnly()
699        {
700                return (($this->mRow['is_splash_only_node'] == 't') ? true : false);
701        }
702
703        /** Set if this node should be a splash-only (no login) node (if enabled in Network configuration)
704         * @param $value The new value, true or false
705         * @return true on success, false on failure */
706        function setIsConfiguredSplashOnly($value)
707        {
708                $retval = true;
709                if ($value != $this->isConfiguredSplashOnly())
710                {
711                        global $db;
712                        $value ? $value = 'TRUE' : $value = 'FALSE';
713                        $retval = $db->execSqlUpdate("UPDATE nodes SET is_splash_only_node = {$value} WHERE node_id = '{$this->getId()}'", false);
714                        $this->refresh();
715                }
716                return $retval;
717        }
718
719        /** The url to show instead of the portal.  If empty, the portal is shown
720         Must be enabled in the Network configuration to have any effect
721         @return a string */
722        function getCustomPortalRedirectUrl()
723        {
724                return $this->mRow['custom_portal_redirect_url'];
725        }
726
727        /** The url to show instead of the portal.  If empty, the portal is shown
728         Must be enabled in the Network configuration to have any effect
729         @return true on success, false on failure */
730        function setCustomPortalRedirectUrl($value)
731        {
732                $retval = true;
733                if ($value != $this->getCustomPortalRedirectUrl())
734                {
735                        global $db;
736                        $value = $db->escapeString($value);
737                        $retval = $db->execSqlUpdate("UPDATE nodes SET custom_portal_redirect_url = '{$value}' WHERE node_id = '{$this->getId()}'", false);
738                        $this->refresh();
739                }
740                return $retval;
741        }
742
743        /**
744         * Retrieves the admin interface of this object
745         *
746         * @return The HTML fragment for this interface
747         *
748         * @access public
749         *
750         * @todo Most of this code will be moved to Hotspot class when the
751         *       abtraction will be completed
752         */
753        public function getAdminUI()
754        {
755            // Init values
756                $html = '';
757
758                if (!User::getCurrentUser()) {
759                        throw new Exception(_('Access denied!'));
760                }
761
762                // Get information about the network
763                $network = $this->getNetwork();
764
765                // Check if user is a admin
766                $_userIsAdmin = User::getCurrentUser()->isSuperAdmin();
767
768                /*
769                 * Hashed node_id
770                 *
771                 * This is a workaround since PHP auto-converts HTTP vars var periods,
772                 * spaces or underscores.
773                 */
774                $hashed_node_id = md5($this->getId());
775
776                /*
777                 * Check for a warning message
778                 */
779                if ($this->_warningMessage != "") {
780                    $html .= InterfaceElements::generateDiv($this->_warningMessage, "errormsg", "node_error");
781                }
782
783                /*
784                 * Begin with admin interface
785                 */
786                $html .= "<fieldset class='admin_container ".get_class($this)."'>\n";
787                $html .= "<legend>"._("Edit a node")."</legend>\n";
788                $html .= "<ul class='admin_element_list'>\n";
789
790                /*
791                 * Display stats
792                 */
793                $_title = _("Statistics");
794                $_data = InterfaceElements::generateInputSubmit("node_" . $this->id . "_get_stats", _("Get access statistics"), "node_get_stats_submit");
795                $html .= InterfaceElements::generateAdminSectionContainer("node_get_stats", $_title, $_data);
796
797                /*
798                 * Information about the node
799                 */
800                $_html_node_information = array();
801
802                // Node ID
803                $_title = _("ID");
804                if ($_userIsAdmin) {
805                $_data = InterfaceElements::generateInputText("node_" . $hashed_node_id . "_id", $this->getId(), "node_id_input");
806                } else {
807                $_data  = htmlspecialchars($this->getId(), ENT_QUOTES);
808                $_data .= InterfaceElements::generateInputHidden("node_" . $hashed_node_id . "_id", $this->getId());
809                }
810                $_html_node_information[] = InterfaceElements::generateAdminSectionContainer("node_id", $_title, $_data);
811
812        //Node content
813        $_html_content = array();
814        $_title = _("Node content");
815        $_data = Content::getLinkedContentUI("node_" . $hashed_node_id . "_content", "node_has_content", "node_id", $this->id, "portal");
816        $html .= InterfaceElements::generateAdminSectionContainer("node_content", $_title, $_data);
817
818                // Name
819                $_title = _("Name");
820                $_data = InterfaceElements::generateInputText("node_" . $hashed_node_id . "_name", $this->getName(), "node_name_input");
821                $_html_node_information[] = InterfaceElements::generateAdminSectionContainer("node_name", $_title, $_data);
822
823        // Creation date
824        $_title = _("Creation date");
825        if ($_userIsAdmin) {
826            $_data = DateTime::getSelectDateTimeUI(new DateTime($this->getCreationDate()), "node_" . $hashed_node_id . "_creation_date", DateTime::INTERFACE_DATETIME_FIELD, "node_creation_date_input");
827        } else {
828            $_data  = htmlspecialchars($this->getCreationDate(), ENT_QUOTES);
829            $_data .= InterfaceElements::generateInputHidden("node_" . $hashed_node_id . "_creation_date", $this->getCreationDate());
830        }
831        $_html_node_information[] = InterfaceElements::generateAdminSectionContainer("node_creation_date", $_title, $_data);
832
833                // Description
834                $_title = _("Description");
835                $_data = InterfaceElements::generateTextarea("node_" . $hashed_node_id . "_description", $this->getDescription(), 50, 5, "node_description_textarea");
836                $_html_node_information[] = InterfaceElements::generateAdminSectionContainer("node_description", $_title, $_data);
837
838                // Civic number
839                $_title = _("Civic number");
840                $_data = InterfaceElements::generateInputText("node_" . $hashed_node_id . "_civic_number", $this->getCivicNumber(), "node_civic_number_input");
841                $_html_node_information[] = InterfaceElements::generateAdminSectionContainer("node_civic_number", $_title, $_data);
842
843                // Street name
844                $_title = _("Street name");
845                $_data = InterfaceElements::generateInputText("node_" . $hashed_node_id . "_street_name", $this->getStreetName(), "node_street_name_input");
846                $_html_node_information[] = InterfaceElements::generateAdminSectionContainer("node_street_name", $_title, $_data);
847
848                // City
849                $_title = _("City");
850                $_data = InterfaceElements::generateInputText("node_" . $hashed_node_id . "_city", $this->getCity(), "node_city_input");
851                $_html_node_information[] = InterfaceElements::generateAdminSectionContainer("node_city", $_title, $_data);
852
853                // Province
854                $_title = _("Province / State");
855                $_data = InterfaceElements::generateInputText("node_" . $hashed_node_id . "_province", $this->getProvince(), "node_province_input");
856                $_html_node_information[] = InterfaceElements::generateAdminSectionContainer("node_province", $_title, $_data);
857
858                // Postal Code
859                $_title = _("Postal code");
860                $_data = InterfaceElements::generateInputText("node_" . $hashed_node_id . "_postal_code", $this->getPostalCode(), "node_postal_code_input");
861                $_html_node_information[] = InterfaceElements::generateAdminSectionContainer("node_postal_code", $_title, $_data);
862
863                // Country
864                $_title = _("Country");
865                $_data = InterfaceElements::generateInputText("node_" . $hashed_node_id . "_country", $this->getCountry(), "node_country_input");
866                $_html_node_information[] = InterfaceElements::generateAdminSectionContainer("node_country", $_title, $_data);
867
868                // Public phone #
869                $_title = _("Public phone number");
870                $_data = InterfaceElements::generateInputText("node_" . $hashed_node_id . "_public_phone", $this->getTelephone(), "node_public_phone_input");
871                $_html_node_information[] = InterfaceElements::generateAdminSectionContainer("node_public_phone", $_title, $_data);
872
873                // Public mail
874                $_title = _("Public email");
875                $_data = InterfaceElements::generateInputText("node_" . $hashed_node_id . "_public_email", $this->getEmail(), "node_public_email_input");
876                $_html_node_information[] = InterfaceElements::generateAdminSectionContainer("node_public_email", $_title, $_data);
877
878                // Homepage URL
879                $_title = _("Homepage URL");
880                $_data = InterfaceElements::generateInputText("node_" . $hashed_node_id . "_homepage_url", $this->getHomePageURL(), "node_homepage_url_input");
881                $_html_node_information[] = InterfaceElements::generateAdminSectionContainer("node_homepage_url", $_title, $_data);
882
883                // Mass transit info
884                $_title = _("Mass transit info");
885                $_data = InterfaceElements::generateInputText("node_" . $hashed_node_id . "_mass_transit_info", $this->getTransitInfo(), "node_mass_transit_info_input");
886                $_html_node_information[] = InterfaceElements::generateAdminSectionContainer("node_mass_transit_info", $_title, $_data);
887
888                // Build section
889                $html .= InterfaceElements::generateAdminSectionContainer("node_information", _("Information about the node"), implode(null, $_html_node_information));
890
891                /*
892                 * Node GIS data
893                 */
894                $_html_node_gis_data = array();
895                $gis_point = $this->getGisLocation();
896
897                // Latitude
898                $_title = _("Latitude");
899                $_data = InterfaceElements::generateInputText("node_" . $hashed_node_id . "_gis_latitude", $gis_point->getLatitude(), "node_" . $hashed_node_id . "_gis_latitude");
900                $_html_node_gis_data[] = InterfaceElements::generateAdminSectionContainer("node_gis_latitude", $_title, $_data);
901
902                // Latitude
903                $_title = _("Longitude");
904                $_data = InterfaceElements::generateInputText("node_" . $hashed_node_id . "_gis_longitude", $gis_point->getLongitude(), "node_" . $hashed_node_id . "_gis_longitude");
905                $_html_node_gis_data[] = InterfaceElements::generateAdminSectionContainer("node_gis_longitude", $_title, $_data);
906
907                // Call the geocoding service, if Google Maps is enabled then use Google Maps to let the user choose a more precise location
908                if (defined('GMAPS_HOTSPOTS_MAP_ENABLED') && GMAPS_HOTSPOTS_MAP_ENABLED === true) {
909                    $_data  = InterfaceElements::generateInputSubmit("geocode_only", _("Geocode only"), "geocode_only_submit");
910                    $_data .= InterfaceElements::generateInputButton("google_maps_geocode", _("Check using Google Maps"), "google_maps_geocode_button", "submit", array("onclick" => "window.open('hotspot_location_map.php?node_id={$this->getId()}', 'hotspot_location', 'toolbar = 0, scrollbars = 1, resizable = 1, location = 0, statusbar = 0, menubar = 0, width = 600, height = 600');"));
911                    $_data .= InterfaceElements::generateDiv("(" . _("Use a geocoding service, then use Google Maps to pinpoint the exact location.") . ")", "admin_section_hint", "node_gis_geocode_hint");
912                } else {
913                    $_data  = InterfaceElements::generateInputSubmit("geocode_only", _("Geocode location"), "geocode_only_submit");
914                    $_data .= InterfaceElements::generateDiv("(" . _("Use a geocoding service") . ")", "admin_section_hint", "node_gis_geocode_hint");
915                }
916
917                $_html_node_gis_data[] = InterfaceElements::generateAdminSectionContainer("node_gis_geocode", "", $_data);
918
919                // Map URL
920                $_title = _("Map URL");
921                $_data = InterfaceElements::generateInputText("node_" . $hashed_node_id . "_map_url", $this->getMapURL(), "node_map_url_input");
922                $_html_node_gis_data[] = InterfaceElements::generateAdminSectionContainer("node_map_url", $_title, $_data);
923
924                // Build section
925                $html .= InterfaceElements::generateAdminSectionContainer("node_gis_data", _("GIS data"), implode(null, $_html_node_gis_data));
926
927                /*
928                 * Node configuration section
929                 */
930                $_html_node_config = array();
931
932                // Deployment status
933                $_title = _("Node deployment status");
934                $_data = $this->getSelectDeploymentStatus("node_" . $hashed_node_id . "_deployment_status");
935                $_html_node_config[] = InterfaceElements::generateAdminSectionContainer("node_deployment_status", $_title, $_data);
936
937                //  is_splash_only_node
938                if ($network->getSplashOnlyNodesAllowed()) {
939                $_title = _("Is this node splash-only (no login)?");
940                $_data = InterfaceElements::generateInputCheckbox("node_" . $hashed_node_id . "_is_splash_only_node", "", _("Yes"), $this->isConfiguredSplashOnly(), "node_is_splash_only_node_radio");
941                $_html_node_config[] = InterfaceElements::generateAdminSectionContainer("node_is_splash_only_node", $_title, $_data);
942                }
943
944                // custom_portal_redirect_url
945                if ($network->getCustomPortalRedirectAllowed()) {
946                $_title = _("URL to show instead of the portal (if this is not empty, the portal will be disabled and this URL will be shown instead)");
947                $_data = InterfaceElements::generateInputText("node_" . $hashed_node_id . "_custom_portal_redirect_url", $this->getCustomPortalRedirectUrl(), "node_custom_portal_redirect_url_input");
948                $_html_node_config[] = InterfaceElements::generateAdminSectionContainer("node_custom_portal_redirect_url", $_title, $_data);
949                }
950
951                // Build section
952                $html .= InterfaceElements::generateAdminSectionContainer("node_config", _("Node configuration"), implode(null, $_html_node_config));
953
954                /*
955                 * Access management
956                 */
957                $_html_access_rights = array();
958
959                // Owners management
960                if ($_userIsAdmin) {
961                $_listData = "";
962
963                foreach ($this->getOwners() as $owner) {
964                    $_listDataContents = InterfaceElements::generateAdminSection("", $owner->getUsername(), InterfaceElements::generateInputSubmit("node_" . $this->getId() . "_owner_" . $owner->GetId() . "_remove", _("Remove owner")));
965                    $_listData .= InterfaceElements::generateLi($_listDataContents, "", "admin_element_item_container node_owner_list");
966                }
967
968            $_listData .= InterfaceElements::generateLi(User::getSelectUserUI("node_" . $this->getId() . "_new_owner", "node_" . $this->getId() . "_new_owner_submit", _("Add owner")) . InterfaceElements::generateDiv("", "clearbr"), "", "admin_element_item_container");
969
970                $_title = _("Node owners");
971                $_data = InterfaceElements::generateUl($_listData, "node_owner_ul", "admin_element_list");
972            $_html_access_rights[] .= InterfaceElements::generateAdminSectionContainer("node_owner", $_title, $_data);
973                }
974
975                // Tech officers management
976                $_listData = "";
977
978                foreach ($this->getTechnicalOfficers() as $tech_officer) {
979                    $_listDataContents = InterfaceElements::generateAdminSection("", $tech_officer->getUsername(), InterfaceElements::generateInputSubmit("node_" . $this->getId() . "_tech_officer_" . $tech_officer->GetId() . "_remove", _("Remove technical officer")));
980                    $_listData .= InterfaceElements::generateLi($_listDataContents, "", "admin_element_item_container node_tech_officer_list");
981                }
982
983            $_listData .= InterfaceElements::generateLi(User::getSelectUserUI("node_" . $this->getId() . "_new_tech_officer", "node_" . $this->getId() . "_new_tech_officer_submit", _("Add technical officer")) . InterfaceElements::generateDiv("", "clearbr"), "", "admin_element_item_container");
984
985                $_title = _("Technical officers");
986                $_data = InterfaceElements::generateUl($_listData, "node_tech_officer_ul", "admin_element_list");
987            $_html_access_rights[] .= InterfaceElements::generateAdminSectionContainer("node_tech_officer", $_title, $_data);
988
989                // Build section
990                $html .= InterfaceElements::generateAdminSectionContainer("node_access_rights", _("Access rights"), implode(null, $_html_access_rights));
991
992                $html .= "</ul>\n";
993                $html .= "</fieldset>";
994
995                return $html;
996        }
997
998        /** Process admin interface of this object.
999        */
1000        public function processAdminUI()
1001        {
1002                $user = User :: getCurrentUser();
1003
1004                if (!$this->isOwner($user) && !$user->isSuperAdmin())
1005                {
1006                        throw new Exception(_('Access denied!'));
1007                }
1008
1009                // Check if user is a admin
1010                $_userIsAdmin = User::getCurrentUser()->isSuperAdmin();
1011
1012                // Information about the node
1013
1014                // Hashed node_id (this is a workaround since PHP auto-converts HTTP vars var periods, spaces or underscores )
1015                $hashed_node_id = md5($this->getId());
1016       // Content processing
1017        $name = "node_{$hashed_node_id}_content";
1018        Content::processLinkedContentUI($name, 'node_has_content', 'node_id', $this->id);
1019
1020                // Name
1021                if ($_userIsAdmin) {
1022                $name = "node_".$hashed_node_id."_name";
1023                $this->setName($_REQUEST[$name]);
1024                } else {
1025                $this->setName($this->getName());
1026                }
1027
1028                // Creation date
1029                if ($_userIsAdmin) {
1030                $name = "node_".$hashed_node_id."_creation_date";
1031                $this->setCreationDate(DateTime::processSelectDateTimeUI($name, DateTime :: INTERFACE_DATETIME_FIELD)->getIso8601FormattedString());
1032                } else {
1033                $this->setCreationDate($this->getCreationDate());
1034                }
1035
1036                // Homepage URL
1037                $name = "node_".$hashed_node_id."_homepage_url";
1038                $this->setHomePageUrl($_REQUEST[$name]);
1039
1040                // Description
1041                $name = "node_".$hashed_node_id."_description";
1042                $this->setDescription($_REQUEST[$name]);
1043
1044                // Map URL
1045                $name = "node_".$hashed_node_id."_map_url";
1046                $this->setMapUrl($_REQUEST[$name]);
1047
1048                // Civic number
1049                $name = "node_".$hashed_node_id."_civic_number";
1050                $this->setCivicNumber($_REQUEST[$name]);
1051
1052                // Street name
1053                $name = "node_".$hashed_node_id."_street_name";
1054                $this->setStreetName($_REQUEST[$name]);
1055
1056                // City
1057                $name = "node_".$hashed_node_id."_city";
1058                $this->setCity($_REQUEST[$name]);
1059
1060                // Province
1061                $name = "node_".$hashed_node_id."_province";
1062                $this->setProvince($_REQUEST[$name]);
1063
1064                // Postal Code
1065                $name = "node_".$hashed_node_id."_postal_code";
1066                $this->setPostalCode($_REQUEST[$name]);
1067
1068                // Country
1069                $name = "node_".$hashed_node_id."_country";
1070                $this->setCountry($_REQUEST[$name]);
1071
1072                // Public phone #
1073                $name = "node_".$hashed_node_id."_public_phone";
1074                $this->setTelephone($_REQUEST[$name]);
1075
1076                // Public mail
1077                $name = "node_".$hashed_node_id."_public_email";
1078                $this->setEmail($_REQUEST[$name]);
1079
1080                // Mass transit info
1081                $name = "node_".$hashed_node_id."_mass_transit_info";
1082                $this->setTransitInfo($_REQUEST[$name]);
1083
1084                // GIS data
1085                // Get a geocoder for a given country
1086                if (!empty ($_REQUEST['geocode_only']))
1087                {
1088                        $geocoder = AbstractGeocoder :: getGeocoder($this->getCountry());
1089                        if ($geocoder != null)
1090                        {
1091                                $geocoder->setCivicNumber($this->getCivicNumber());
1092                                $geocoder->setStreetName($this->getStreetName());
1093                                $geocoder->setCity($this->getCity());
1094                                $geocoder->setProvince($this->getProvince());
1095                                $geocoder->setPostalCode($this->getPostalCode());
1096                                if ($geocoder->validateAddress() === true)
1097                                {
1098                                        if (($point = $geocoder->getGisLocation()) !== null)
1099                                                $this->setGisLocation($point);
1100                                        else
1101                                                $this->_warningMessage = _("It appears that the Geocoder could not be reached or could not geocode the given address.");
1102                                }
1103                                else
1104                                        $this->_warningMessage = _("You must enter a valid address.");
1105                        }
1106                }
1107                else
1108                {
1109                        // Use what has been set by the user.
1110                        $gis_lat_name = "node_".$hashed_node_id."_gis_latitude";
1111                        $gis_long_name = "node_".$hashed_node_id."_gis_longitude";
1112                        $this->setGisLocation(new GisPoint($_REQUEST[$gis_lat_name], $_REQUEST[$gis_long_name], .0));
1113                }
1114
1115                // Statistics
1116                $name = "node_{$this->id}_get_stats";
1117                if (!empty ($_REQUEST[$name]))
1118                        header("Location: stats.php?node_id=".urlencode($this->getId()));
1119
1120                // Node configuration section
1121
1122                $network = $this->getNetwork();
1123
1124                // Deployment status
1125                $name = "node_".$hashed_node_id."_deployment_status";
1126                $this->setDeploymentStatus(self :: processSelectDeploymentStatus($name));
1127
1128                //  is_splash_only_node
1129                if ($network->getSplashOnlyNodesAllowed())
1130                {
1131                        $name = "node_".$hashed_node_id."_is_splash_only_node";
1132                        $this->setIsConfiguredSplashOnly(empty ($_REQUEST[$name]) ? false : true);
1133                }
1134
1135                // custom_portal_redirect_url
1136                if ($network->getCustomPortalRedirectAllowed())
1137                {
1138                        $name = "node_".$hashed_node_id."_custom_portal_redirect_url";
1139                        $this->setCustomPortalRedirectUrl($_REQUEST[$name]);
1140                }
1141
1142                // End Node configuration section
1143
1144                // Owners processing
1145                if ($_userIsAdmin) {
1146                // Rebuild user id, and delete if it was selected
1147                foreach ($this->getOwners() as $owner)
1148                {
1149                        $name = "node_{$this->getId()}_owner_{$owner->GetId()}_remove";
1150                        if (!empty ($_REQUEST[$name]))
1151                        {
1152                                if ($this->isOwner($owner))
1153                                        $this->removeOwner($owner);
1154                                else
1155                                        $this->_warningMessage = _("Invalid user!");
1156                        }
1157                }
1158
1159                $name = "node_{$this->getId()}_new_owner_submit";
1160                if (!empty ($_REQUEST[$name]))
1161                {
1162                        $name = "node_{$this->getId()}_new_owner";
1163                        $owner = User :: processSelectUserUI($name);
1164                        if ($owner)
1165                        {
1166                                if ($this->isOwner($owner))
1167                                        $this->_warningMessage = _("The user is already an owner of this node.");
1168                                else
1169                                        $this->addOwner($owner);
1170                        }
1171                }
1172                }
1173
1174                // Technical officers processing
1175                // Rebuild user id, and delete if it was selected
1176                foreach ($this->getTechnicalOfficers() as $tech_officer)
1177                {
1178                        $name = "node_{$this->getId()}_tech_officer_{$tech_officer->GetId()}_remove";
1179                        if (!empty ($_REQUEST[$name]))
1180                        {
1181                                if ($this->isTechnicalOfficer($tech_officer))
1182                                        $this->removeTechnicalOfficer($tech_officer);
1183                                else
1184                                        $this->_warningMessage = _("Invalid user!");
1185                        }
1186                }
1187
1188                $name = "node_{$this->getId()}_new_tech_officer_submit";
1189                if (!empty ($_REQUEST[$name]))
1190                {
1191                        $name = "node_{$this->getId()}_new_tech_officer";
1192                        $tech_officer = User :: processSelectUserUI($name);
1193                        if ($tech_officer)
1194                        {
1195                                if ($this->isTechnicalOfficer($tech_officer))
1196                                        $this->_warningMessage = _("The user is already a technical officer of this node.");
1197                                else
1198                                        $this->addTechnicalOfficer($tech_officer);
1199                        }
1200                }
1201
1202                // Id
1203                $name = "node_".$hashed_node_id."_id";
1204                $this->setId($_REQUEST[$name]);
1205        }
1206
1207        // Redirect to this node's portal page
1208        public function getUserUI()
1209        {
1210                header("Location: ".BASE_SSL_PATH."portal/?gw_id=".$this->getId());
1211        }
1212
1213        /** Add content to this node */
1214        public function addContent(Content $content)
1215        {
1216                global $db;
1217                $content_id = $db->escapeString($content->getId());
1218                $sql = "INSERT INTO node_has_content (node_id, content_id) VALUES ('$this->id','$content_id')";
1219                $db->execSqlUpdate($sql, false);
1220                exit;
1221        }
1222
1223        /** Remove content from this node */
1224        public function removeContent(Content $content)
1225        {
1226                global $db;
1227                $content_id = $db->escapeString($content->getId());
1228                $sql = "DELETE FROM node_has_content WHERE node_id='$this->id' AND content_id='$content_id'";
1229                $db->execSqlUpdate($sql, false);
1230        }
1231
1232        /**Get an array of all Content linked to this node
1233         * @param boolean $exclude_subscribed_content
1234        * @param User $subscriber The User object used to discriminate the content
1235        * @param $display_page Only select the content to be displayed in thios
1236        * area.  Defaults to 'portal_page'
1237        * @return an array of Content or an empty arrray */
1238        /*function getAllContent($exclude_subscribed_content = false, $subscriber = null, $display_page = 'portal')
1239        {
1240                global $db;
1241                $retval = array ();
1242                $content_rows = null;
1243                // Get all network, but exclude user subscribed content if asked
1244                if ($exclude_subscribed_content == true && $subscriber)
1245                        $sql = "SELECT content_id FROM node_has_content WHERE node_id='{$this->id}' AND display_page='$display_page' AND content_id NOT IN (SELECT content_id FROM user_has_content WHERE user_id = '{$subscriber->getId()}') ORDER BY subscribe_timestamp DESC";
1246                else
1247                        $sql = "SELECT content_id FROM node_has_content WHERE node_id='{$this->id}' AND display_page='$display_page' ORDER BY subscribe_timestamp DESC";
1248                $db->execSql($sql, $content_rows, false);
1249
1250                if ($content_rows != null)
1251                {
1252                        foreach ($content_rows as $content_row)
1253                        {
1254                                $retval[] = Content::getObject($content_row['content_id']);
1255                        }
1256                }
1257                return $retval;
1258        }*/
1259
1260        /** Get an array of all artistic and locative Content for this hotspot
1261        * @return an array of Content or an empty arrray */
1262        function getAllLocativeArtisticContent()
1263        {
1264                global $db;
1265                $retval = array ();
1266                $sql = "SELECT * FROM content_group JOIN content ON (content.content_id = content_group.content_group_id) JOIN node_has_content ON (node_has_content.content_id = content_group.content_group_id AND node_has_content.node_id = '{$this->getId()}') WHERE is_persistent = true AND is_artistic_content = true AND is_locative_content = true ORDER BY subscribe_timestamp DESC";
1267                $content_rows = null;
1268                $db->execSql($sql, $content_rows, false);
1269                if ($content_rows != null)
1270                {
1271                        foreach ($content_rows as $content_row)
1272                        {
1273                                // Create a content group object and grab only those that have content for the current Node
1274                                $content_group = Content :: getObject($content_row['content_group_id']);
1275                                if ($content_group->getDisplayNumElements() >= 1)
1276                                {
1277                                        if ($content_group->isDisplayableAt($this))
1278                                        {
1279                                                // Disable logging and allow content to expand ( if possible )
1280                                                $content_group->setExpandStatus(true);
1281                                                $content_group->setLoggingStatus(false);
1282                                                $retval[] = $content_group;
1283                                        }
1284                                }
1285                        }
1286                }
1287                return $retval;
1288        }
1289
1290        /** The list of users online at this node
1291         * @return An array of User object, or en empty array */
1292        function getOnlineUsers()
1293        {
1294                global $db;
1295                $retval = array ();
1296                $users = null;
1297                $db->execSql("SELECT users.user_id FROM users,connections WHERE connections.token_status='".TOKEN_INUSE."' AND users.user_id=connections.user_id AND connections.node_id='{$this->id}'", $users, false);
1298                if ($users != null)
1299                {
1300                        foreach ($users as $user_row)
1301                        {
1302                                $retval[] = User :: getObject($user_row['user_id']);
1303                        }
1304                }
1305                return $retval;
1306        }
1307
1308        /** Find out how many users are online this specific Node
1309         * @return Number of online users
1310         */
1311        function getNumOnlineUsers()
1312        {
1313                global $db;
1314                $retval = array ();
1315                $row = null;
1316                if(!$this->isConfiguredSplashOnly())
1317                        $db->execSqlUniqueRes("SELECT COUNT(DISTINCT users.user_id) as count FROM users,connections WHERE connections.token_status='".TOKEN_INUSE."' AND users.user_id=connections.user_id AND connections.node_id='{$this->id}'", $row, false);
1318                else
1319                        $db->execSqlUniqueRes("SELECT COUNT(DISTINCT connections.user_mac) as count FROM connections WHERE connections.token_status='".TOKEN_INUSE."' AND connections.node_id='{$this->id}'", $row, false);
1320                return $row['count'];
1321        }
1322
1323        /** The list of all real owners of this node
1324         * @return An array of User object, or en empty array */
1325        function getOwners()
1326        {
1327                global $db;
1328                $retval = array ();
1329                $owners = null;
1330                $db->execSql("SELECT user_id FROM node_stakeholders WHERE is_owner = true AND node_id='{$this->id}'", $owners, false);
1331                if ($owners != null)
1332                {
1333                        foreach ($owners as $owner_row)
1334                        {
1335                                $retval[] = User :: getObject($owner_row['user_id']);
1336                        }
1337                }
1338                return $retval;
1339        }
1340
1341        /** The list of all Technical officers of this node.
1342         * Technical officers are displayed highlited and in the online user's list,
1343         * and are contacted when the Node goes down.
1344         * @return An array of User object, or en empty array */
1345        function getTechnicalOfficers()
1346        {
1347                global $db;
1348                $retval = array ();
1349                $officers = null;
1350                $db->execSql("SELECT user_id FROM node_stakeholders WHERE is_tech_officer = true AND node_id='{$this->id}'", $officers, false);
1351                if ($officers != null)
1352                {
1353                        foreach ($officers as $officer_row)
1354                        {
1355                                $retval[] = User :: getObject($officer_row['user_id']);
1356                        }
1357                }
1358                return $retval;
1359        }
1360
1361        /** Associates an owner to this node
1362         * @param User
1363         */
1364        function addOwner(User $user)
1365        {
1366                global $db;
1367                $rows = null;
1368                $db->execSql("SELECT * FROM node_stakeholders WHERE node_id = '{$this->getId()}' AND user_id = '{$user->getId()}'", $rows, false);
1369                if (!$rows)
1370                {
1371                        if (!$db->execSqlUpdate("INSERT INTO node_stakeholders (node_id, user_id, is_owner) VALUES ('{$this->getId()}','{$user->getId()}', true)", false))
1372                                throw new Exception(_('Could not add owner'));
1373                }
1374                else
1375                        if (!$db->execSqlUpdate("UPDATE node_stakeholders SET is_owner = true WHERE node_id = '{$this->getId()}' AND user_id = '{$user->getId()}';", false))
1376                                throw new Exception(_('Could not add owner'));
1377        }
1378
1379        /** Associates a technical officer ( tech support ) to this node
1380         * @param User
1381         */
1382        function addTechnicalOfficer(User $user)
1383        {
1384                global $db;
1385                $rows = null;
1386                $db->execSql("SELECT * FROM node_stakeholders WHERE node_id = '{$this->getId()}' AND user_id = '{$user->getId()}'", $rows, false);
1387                if (!$rows)
1388                {
1389                        if (!$db->execSqlUpdate("INSERT INTO node_stakeholders (node_id, user_id, is_tech_officer) VALUES ('{$this->getId()}','{$user->getId()}', true)", false))
1390                                throw new Exception(_('Could not add tech officer'));
1391                }
1392                else
1393                        if (!$db->execSqlUpdate("UPDATE node_stakeholders SET is_tech_officer = true WHERE node_id = '{$this->getId()}' AND user_id = '{$user->getId()}';", false))
1394                                throw new Exception(_('Could not set existing user as tech officer'));
1395        }
1396
1397        /** Remove owner flag for a stakeholder of this node
1398         * @param User
1399         */
1400        function removeOwner(User $user)
1401        {
1402                global $db;
1403                if (!$db->execSqlUpdate("UPDATE node_stakeholders SET is_owner = false WHERE node_id = '{$this->getId()}' AND user_id = '{$user->getId()}';", false))
1404                        throw new Exception(_('Could not remove owner'));
1405        }
1406
1407        /** Remove technical officer flag for a stakeholder of this node
1408         * @param User
1409         */
1410        function removeTechnicalOfficer(User $user)
1411        {
1412                global $db;
1413                if (!$db->execSqlUpdate("UPDATE node_stakeholders SET is_tech_officer = false WHERE node_id = '{$this->getId()}' AND user_id = '{$user->getId()}';", false))
1414                        throw new Exception(_('Could not remove tech officer'));
1415        }
1416
1417        /** Is the user an owner of the Node?
1418         * @return true our false*/
1419        function isOwner(User $user)
1420        {
1421                global $db;
1422                if ($user != null)
1423                {
1424                        $user_id = $user->getId();
1425                        $retval = false;
1426                        $row = null;
1427                        $db->execSqlUniqueRes("SELECT * FROM node_stakeholders WHERE is_owner = true AND node_id='{$this->id}' AND user_id='{$user_id}'", $row, false);
1428                        if ($row != null)
1429                        {
1430                                $retval = true;
1431                        }
1432                }
1433                return $retval;
1434        }
1435
1436        /** Is the user a technical officer of the Node?
1437         * @return true our false*/
1438        function isTechnicalOfficer(User $user)
1439        {
1440                global $db;
1441                if ($user != null)
1442                {
1443                        $user_id = $user->getId();
1444                        $retval = false;
1445                        $row = null;
1446                        $db->execSqlUniqueRes("SELECT * FROM node_stakeholders WHERE is_tech_officer = true AND node_id='{$this->id}' AND user_id='{$user_id}'", $row, false);
1447                        if ($row != null)
1448                        {
1449                                $retval = true;
1450                        }
1451                }
1452                return $retval;
1453        }
1454
1455        /**
1456         * Checks if an node exists
1457         *
1458         * @param string $id Id of node to be checked
1459         *
1460         * @return bool True if node exists, else false
1461         *
1462         * @static
1463         * @access private
1464         */
1465        private static function nodeExists($id)
1466        {
1467            // Define globals
1468                global $db;
1469
1470                // Init values
1471                $retval = false;
1472
1473                $id_str = $db->escapeString($id);
1474                $sql = "SELECT * FROM nodes WHERE node_id='{$id_str}'";
1475                $row = null;
1476                $db->execSqlUniqueRes($sql, $row, false);
1477
1478                if ($row != null) {
1479                        $retval = true;
1480                }
1481
1482                return $retval;
1483        }
1484
1485        /** Reloads the object from the database.  Should normally be called after a set operation */
1486        protected function refresh()
1487        {
1488                $this->__construct($this->id);
1489        }
1490
1491}
1492
1493/*
1494 * Local variables:
1495 * tab-width: 4
1496 * c-basic-offset: 4
1497 * c-hanging-comment-ender-p: nil
1498 * End:
1499 */
Note: See TracBrowser for help on using the browser.