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

Revision 767, 47.8 KB (checked in by fproulx, 8 years ago)

2005-09-25 Francois Proulx <francois.proulx@…>

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