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

Revision 877, 49.3 KB (checked in by fproulx, 7 years ago)

2005-12-29 Fran�ois Proulx <francois.proulx@…>

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