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

Revision 704, 41.7 KB (checked in by fproulx, 8 years ago)

2005-08-31 Francois Proulx <francois.proulx@…>

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