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

Revision 727, 46.3 KB (checked in by aprilp, 8 years ago)

*** empty log message ***

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