root/trunk/wifidog-auth/wifidog/classes/Network.php @ 1436

Revision 1436, 82.8 KB (checked in by gbastien, 3 years ago)
  • Property svn:eol-style set to native
  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
Line 
1<?php
2
3/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
4
5// +-------------------------------------------------------------------+
6// | WiFiDog Authentication Server                                     |
7// | =============================                                     |
8// |                                                                   |
9// | The WiFiDog Authentication Server is part of the WiFiDog captive  |
10// | portal suite.                                                     |
11// +-------------------------------------------------------------------+
12// | PHP version 5 required.                                           |
13// +-------------------------------------------------------------------+
14// | Homepage:     http://www.wifidog.org/                             |
15// | Source Forge: http://sourceforge.net/projects/wifidog/            |
16// +-------------------------------------------------------------------+
17// | This program is free software; you can redistribute it and/or     |
18// | modify it under the terms of the GNU General Public License as    |
19// | published by the Free Software Foundation; either version 2 of    |
20// | the License, or (at your option) any later version.               |
21// |                                                                   |
22// | This program is distributed in the hope that it will be useful,   |
23// | but WITHOUT ANY WARRANTY; without even the implied warranty of    |
24// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the     |
25// | GNU General Public License for more details.                      |
26// |                                                                   |
27// | You should have received a copy of the GNU General Public License |
28// | along with this program; if not, contact:                         |
29// |                                                                   |
30// | Free Software Foundation           Voice:  +1-617-542-5942        |
31// | 59 Temple Place - Suite 330        Fax:    +1-617-542-2652        |
32// | Boston, MA  02111-1307,  USA       gnu@gnu.org                    |
33// |                                                                   |
34// +-------------------------------------------------------------------+
35
36/**
37 * @package    WiFiDogAuthServer
38 * @author     Benoit Grégoire <benoitg@coeus.ca>
39 * @author     Max Horváth <max.horvath@freenet.de>
40 * @copyright  2005-2006 Benoit Grégoire, Technologies Coeus inc.
41 * @copyright  2006 Max Horváth, Horvath Web Consulting
42 * @version    Subversion $Id$
43 * @link       http://www.wifidog.org/
44 */
45
46/**
47 * Load required classes
48 */
49require_once('classes/Content.php');
50require_once('classes/User.php');
51require_once('classes/Node.php');
52require_once('classes/NodeGroup.php');
53require_once('classes/GisPoint.php');
54require_once('classes/Cache.php');
55require_once('classes/ThemePack.php');
56require_once('classes/Security.php');
57require_once('classes/HotspotGraphElement.php');
58
59/**
60 * Abstract a Network.
61 *
62 * A network is an administrative entity with it's own users, nodes and authenticator.
63 *
64 * @package    WiFiDogAuthServer
65 * @author     Benoit Grégoire <benoitg@coeus.ca>
66 * @author     Max Horváth <max.horvath@freenet.de>
67 * @copyright  2005-2006 Benoit Grégoire, Technologies Coeus inc.
68 * @copyright  2006 Max Horváth, Horvath Web Consulting
69 */
70class Network extends HotspotGraphElement
71{
72    /** Object cache for the object factory (getObject())*/
73
74    /**
75     * Get an instance of the object
76     *
77     * @param string $id The object id
78     *
79     * @return mixed The Content object, or null if there was an error
80     *               (an exception is also thrown)
81     *
82     * @see GenericObject
83     * @static
84     * @access public
85     */
86    public static function &getObject($id)
87    {
88        return HotspotGraphElement::getObject($id, 'Network');
89    }
90
91    /** Free an instanciated object
92     * @param $id The id to free
93     * Thanks and so long for all the ram.
94     */
95    public static function freeObject($id)
96    {
97        HotspotGraphElement::freeObject($id, 'Network');
98    }
99
100    /**
101     * Get all the Networks configured on this server
102     *
103     * @return array An array of Network objects.  The default network is
104     *               returned first
105     *
106     * @static
107     * @access public
108     */
109    public static function getAllNetworks()
110    {
111        $retval = array ();
112        $db = AbstractDb::getObject();
113        $sql = "SELECT network_id FROM networks";
114        $network_rows = null;
115        $db->execSql($sql, $network_rows, false);
116        if ($network_rows == null) {
117            throw new Exception(_("Network::getAllNetworks:  Fatal error: No networks in the database!"));
118        }
119        foreach ($network_rows as $network_row) {
120            $retval[] = self::getObject($network_row['network_id']);
121        }
122        return $retval;
123    }
124
125    /**
126     * Get the default network
127     *
128     * @return object A Network object, NEVER returns null.
129     *
130     * @static
131     * @access public
132     */
133    public static function getDefaultNetwork()
134    {
135        $retval = null;
136        $vhost = VirtualHost :: getCurrentVirtualHost();
137        if ($vhost == null) {
138            $vhost = VirtualHost :: getDefaultVirtualHost();
139        }
140        return $vhost->getDefaultNetwork();
141    }
142
143    /**
144     * Get the current network for which the portal is displayed or to which a
145     * user is physically connected.
146     *
147     * @param bool $real_network_only NOT IMPLEMENTED YET true or false.  If
148     *                                true, the real physical network where the
149     *                                user is connected is returned, and
150     *                                the node set by setCurrentNode is ignored.
151     *
152     * @return objetc A Network object, NEVER returns null.
153     *
154     * @static
155     * @access public
156     */
157    public static function getCurrentNetwork($real_network_only = false)
158    {
159        $retval = null;
160        $current_node = Node :: getCurrentNode();
161
162        if ($current_node != null) {
163            $retval = $current_node->getNetwork();
164        } else {
165            $retval = Network :: getDefaultNetwork();
166        }
167
168        return $retval;
169    }
170
171    /**
172     * Create a new Network object in the database
173     *
174     * @param string $network_id The network id of the new network.  If absent,
175     *                           will be assigned a guid.
176     *
177     * @return mixed The newly created object, or null if there was an error
178     *
179     * @see GenericObject
180     * @static
181     * @access public
182     */
183    public static function createNewObject($network_id = null)
184    {
185       
186        $db = AbstractDb::getObject();
187        if (empty ($network_id)) {
188            $network_id = get_guid();
189        }
190        $network_id = $db->escapeString($network_id);
191
192        $sql = "INSERT INTO networks (network_id, network_authenticator_class) VALUES ('$network_id', 'AuthenticatorLocalUser')";
193
194        if (!$db->execSqlUpdate($sql, false)) {
195            throw new Exception(_('Unable to insert the new network in the database!'));
196        }
197       
198        HotspotGraphElement::createNewObject($network_id, 'Network');
199       
200        $object = self::getObject($network_id);
201        require_once('classes/Stakeholder.php');
202        Stakeholder::add(null, Role::getObject('NETWORK_OWNER'), $object);
203        return $object;
204    }
205
206    /**
207     * Get an interface to pick an object of this class
208     *
209     * If there is only one server available, no interface is actually shown
210     *
211     * @param string $user_prefix         A identifier provided by the
212     *                                    programmer to recognise it's generated
213     *                                    html form
214     *  @param string $userData=null Array of contextual data optionally sent to the method.
215     *  The function must still function if none of it is present.
216     *
217     * This method understands:
218     *  $userData['preSelectedObject'] An optional Object of this class to be selected.
219     *  $userData['additionalWhere'] Additional SQL conditions for the
220     *                                    objects to select
221     *  $userData['allowEmpty'] boolean Allow not selecting any object
222     * @return string HTML markup
223
224     */
225    /**
226     * Get an interface to pick a network
227     *
228     * If there is only one network available, no interface is actually shown
229     *
230     * @param string $user_prefix          A identifier provided by the
231     *                                     programmer to recognise it's
232     *                                     generated html form
233     *
234     * @param string $userData=null Array of contextual data optionally sent to the method.
235     *  The function must still function if none of it is present.
236     *
237     * This method understands:
238     *  $userData['preSelectedObject'] An optional object to pre-select.
239     *  $userData['additionalWhere'] Additional SQL conditions for the
240     *                                    objects to select
241     *  $userData['allowEmpty'] boolean Allow not selecting any object
242     *  $userData['onlyNetwoksAllowingSignup'] boolean Only list networks allowing user self-signup
243     * @return string HTML markup
244
245     */
246    public static function getSelectUI($user_prefix, $userData=null)
247    {
248        $userData=$userData===null?array():$userData;
249        $html = '';
250        $name = $user_prefix;
251        //pretty_print_r($userData);
252        array_key_exists('preSelectedObject',$userData)?(empty($userData['preSelectedObject'])?$selected_id=null:$selected_id=$userData['preSelectedObject']->getId()):$selected_id=self::getDefaultNetwork()->getId();
253        !empty($userData['additionalWhere'])?$additional_where=$userData['additionalWhere']:$additional_where=null;
254        !empty($userData['allowEmpty'])?$allow_empty=$userData['allowEmpty']:$allow_empty=false;
255        !empty($userData['nullCaptionString'])?$nullCaptionString=$userData['nullCaptionString']:$nullCaptionString=null;
256        !empty($userData['onChange'])?$onChangeString=$userData['onChange']:$onChangeString="";
257        !empty($userData['onlyNetwoksAllowingSignup'])?$onlyNetwoksAllowingSignup=$userData['onlyNetwoksAllowingSignup']:$onlyNetwoksAllowingSignup=false;
258
259        $db = AbstractDb::getObject();
260        $sql = "SELECT network_id, name FROM networks WHERE 1=1 $additional_where";
261        $network_rows = null;
262        $db->execSql($sql, $network_rows, false);
263        if ($network_rows == null) {
264            throw new Exception(_("Network::getAllNetworks:  Fatal error: No networks in the database!"));
265        }
266
267        $number_of_networks = count($network_rows);
268        if ($number_of_networks > 1) {
269            $i = 0;
270            foreach ($network_rows as $network_row) {
271               
272                if($onlyNetwoksAllowingSignup==false || (self::getObject($network_row['network_id'])->getAuthenticator()->isRegistrationPermitted())==true){
273                    $tab[$i][0] = $network_row['network_id'];
274                    $tab[$i][1] = $network_row['name'];
275                    $i ++;
276                }
277            }
278            $html .= _("Network:")." \n";
279            $html .= FormSelectGenerator :: generateFromArray($tab, $selected_id, $name, null, $allow_empty, $nullCaptionString, "onchange='$onChangeString'");
280
281        } else {
282            foreach ($network_rows as $network_row) //iterates only once...
283            {
284                $html .= _("Network:")." \n";
285                $html .= " $network_row[name] ";
286                $html .= "<input type='hidden' name='$name' value='".htmlspecialchars($network_row['network_id'], ENT_QUOTES, 'UTF-8')."'>";
287            }
288        }
289
290        return $html;
291    }
292
293    /**
294     * Get the selected Network object.
295     *
296     * @param string $user_prefix A identifier provided by the programmer to
297     *                            recognise it's generated form
298     *
299     * @return mixed The network object or null
300
301     */
302    public static function processSelectUI($user_prefix)
303    {
304        $name = "{$user_prefix}";
305        if (!empty ($_REQUEST[$name])) {
306            return self::getObject($_REQUEST[$name]);
307        } else {
308            return null;
309        }
310    }
311
312    /**
313     * Get an interface to create a new network.
314     *
315     * @return string HTML markup
316     *
317     * @static
318     * @access public
319     */
320    public static function getCreateNewObjectUI()
321    {
322        // Init values
323        $html = '';
324
325        $html .= _("Create a new network with ID")." \n";
326        $name = "new_network_id";
327        $html .= "<input type='text' size='10' name='{$name}'>\n";
328        return $html;
329    }
330
331    /**
332     * Process the new object interface.
333     *
334     * Will return the new object if the user has the credentials and the form
335     * was fully filled.
336     *
337     * @return mixed The Network object or null if no new Network was created.
338     *
339     * @static
340     * @access public
341     */
342    public static function processCreateNewObjectUI()
343    {
344        // Init values
345        $retval = null;
346        $name = "new_network_id";
347
348        if (!empty($_REQUEST[$name])) {
349            $network_id = $_REQUEST[$name];
350
351            if (!preg_match('/^[0-9a-zA-Z_-]+$/', $network_id)) {
352            throw new Exception(_("The Network ID entered was not valid. It must only contain Alphanumerical Characters, Hyphens and Underscores e.g. My_Network-6"));
353            return;
354            }
355
356            if ($network_id) {
357                Security::requirePermission(Permission::P('SERVER_PERM_ADD_NEW_NETWORK'), Server::getServer());
358                $retval = self::createNewObject($network_id);
359            }
360        }
361
362        return $retval;
363    }
364
365    /**
366     * Constructor
367     *
368     * @param string $p_network_id
369     *
370     * @return void
371     *
372     * @access private
373     */
374    protected function __construct($p_network_id)
375    {
376        $db = AbstractDb::getObject();
377        if ($p_network_id == "")
378            $p_network_id = self::getDefaultNetwork()->getId();
379        $network_id_str = $db->escapeString($p_network_id);
380
381        $sql = "SELECT *, EXTRACT(EPOCH FROM validation_grace_time) as validation_grace_time_seconds FROM networks WHERE network_id='$network_id_str'";
382        $row = null;
383        $db->execSqlUniqueRes($sql, $row, false);
384        if ($row == null) {
385            throw new Exception("The network with id $network_id_str could not be found in the database");
386        }
387        $this->_row = $row;
388        $this->_id = $p_network_id;
389        parent::__construct($this->_id, 'Network');
390    }
391
392    public function __toString()
393    {
394        return $this->getName();
395    }
396
397    /**
398     * Retreives the network name
399     *
400     * @return string The id
401     *
402     * @access public
403     */
404    public function getTechSupportEmail()
405    {
406        return $this->_row['tech_support_email'];
407    }
408
409    /**
410     * Set the network's tech support and information email address
411     *
412     * @param string $value The new value
413     *
414     * @return bool True on success, false on failure
415     *
416     * @access public
417     */
418    public function setTechSupportEmail($value)
419    {
420        // Init values
421        $retval = true;
422
423        if ($value != $this->getName()) {
424            $db = AbstractDb::getObject();
425            $value = $db->escapeString($value);
426            $retval = $db->execSqlUpdate("UPDATE networks SET tech_support_email = '{$value}' WHERE network_id = '{$this->getId()}'", false);
427            $this->refresh();
428        }
429
430        return $retval;
431    }
432
433    /**
434     * Retrieves the network name
435     *
436     * @return string A string
437     *
438     * @access public
439     */
440    public function getName()
441    {
442        return $this->_row['name'];
443    }
444
445    /**
446     * Set the network's name
447     *
448     * @param string $value The new value
449     *
450     * @return bool True on success, false on failure
451     *
452     * @access public
453     */
454    public function setName($value)
455    {
456        // Init values
457        $retval = true;
458
459        if ($value != $this->getName()) {
460            $db = AbstractDb::getObject();
461            $value = $db->escapeString($value);
462            $retval = $db->execSqlUpdate("UPDATE networks SET name = '{$value}' WHERE network_id = '{$this->getId()}'", false);
463            $this->refresh();
464        }
465
466        return $retval;
467    }
468
469    /**
470     * Retrieves the network's theme pack
471     *
472     * @return mixed ThemePack or null
473     *
474     * @access public
475     */
476    public function getThemePack()
477    {
478        if (!empty ($this->_row['theme_pack'])) {
479            return ThemePack::getObject($this->_row['theme_pack']);
480        } else {
481            return null;
482        }
483    }
484
485    /**
486     * Set the network's name
487     *
488     * @param string $value The new ThemePack, or null
489     *
490     * @return bool True on success, false on failure
491     *
492     * @access public
493     */
494    public function setThemePack($value)
495    {
496        // Init values
497        $retval = true;
498
499        if ($value != $this->getThemePack()) {
500            $db = AbstractDb::getObject();
501            empty($value)?$value="NULL":$value="'".$db->escapeString($value->getId())."'";
502            $retval = $db->execSqlUpdate("UPDATE networks SET theme_pack = {$value} WHERE network_id = '{$this->getId()}'", false);
503            $this->refresh();
504        }
505
506        return $retval;
507    }
508
509    /**
510     * Retrieves the network's creation date
511     *
512     * @return string Network's creation date
513     *
514     * @access public
515     */
516    public function getCreationDate()
517    {
518        return $this->_row['creation_date'];
519    }
520
521    /**
522     * Set the network's creation date
523     *
524     * @param string $value The new creation date
525     *
526     * @return bool True on success, false on failure
527     */
528    public function setCreationDate($value)
529    {
530
531        $db = AbstractDb::getObject();
532
533        // Init values
534        $retVal = true;
535
536        if ($value != $this->getCreationDate()) {
537            $value = $db->escapeString($value);
538            $retVal = $db->execSqlUpdate("UPDATE networks SET creation_date = '{$value}' WHERE network_id = '{$this->getId()}'", false);
539            $this->refresh();
540        }
541
542        return $retVal;
543    }
544
545    /**
546     * Retreives the network's homepage url
547     *
548     * @return string The id
549     *
550     * @access public
551     */
552    public function getWebSiteURL()
553    {
554        return $this->_row['homepage_url'];
555    }
556
557    /**
558     * Set the network's homepage url
559     *
560     * @param string $value The new value
561     *
562     * @return bool True on success, false on failure
563     *
564     * @access public
565     */
566    public function setWebSiteUrl($value)
567    {
568        // Init values
569        $retval = true;
570
571        if ($value != $this->getName()) {
572            $db = AbstractDb::getObject();
573            $value = $db->escapeString($value);
574            $retval = $db->execSqlUpdate("UPDATE networks SET homepage_url = '{$value}' WHERE network_id = '{$this->getId()}'", false);
575            $this->refresh();
576        }
577
578        return $retval;
579    }
580
581    /**
582     * Retreives the network's authenticator's class name.
583     *
584     * @return string Name of authenticator's class
585     */
586    public function getAuthenticatorClassName()
587    {
588        return $this->_row['network_authenticator_class'];
589    }
590
591    /**
592     * Set the network's authenticator's class.
593     *
594     * The subclass of Authenticator to be used for user authentication
595     * (ex: AuthenticatorRadius)
596     *
597     * @param string $value The class name of a  subclass of Authenticator
598     *
599     * @return bool True on success, false on failure
600     */
601    public function setAuthenticatorClassName($value)
602    {
603
604        $db = AbstractDb::getObject();
605
606        // Init values
607        $retval = true;
608
609        if ($value != $this->getAuthenticatorClassName()) {
610            $value = $db->escapeString($value);
611            $retval = $db->execSqlUpdate("UPDATE networks SET network_authenticator_class = '{$value}' WHERE network_id = '{$this->getId()}'", false);
612            $this->refresh();
613        }
614
615        return $retval;
616    }
617
618    /**
619     * Retreives the authenticator's parameters
620     *
621     * @return string Authenticator's parameters
622     */
623    public function getAuthenticatorConstructorParams()
624    {
625        return $this->_row['network_authenticator_params'];
626    }
627
628    /**
629     * The explicit parameters to be passed to the authenticator's constructor
630     * (ex: 'my_network_id', '192.168.0.11', 1812, 1813, 'secret_key',
631     * 'CHAP_MD5')
632     *
633     * @param string $value The new value
634     *
635     * @return bool True on success, false on failure
636     */
637    public function setAuthenticatorConstructorParams($value)
638    {
639
640        $db = AbstractDb::getObject();
641
642        // init values
643        $retval = true;
644
645        if ($value != $this->getAuthenticatorConstructorParams()) {
646            $value = $db->escapeString($value);
647            $retval = $db->execSqlUpdate("UPDATE networks SET network_authenticator_params = '{$value}' WHERE network_id = '{$this->getId()}'", false);
648            $this->refresh();
649        }
650
651        return $retval;
652    }
653
654    /**
655     * Get the Authenticator object for this network
656     *
657     * @return object A subclass of Authenticator
658     */
659    public function getAuthenticator()
660    {
661        require_once ('classes/Authenticator.php');
662
663        // Include only the authenticator we are about to use
664        require_once ("classes/Authenticators/".$this->_row['network_authenticator_class'].".php");
665
666        if (strpos($this->_row['network_authenticator_params'], ';') != false) {
667            throw new Exception("Network::getAuthenticator(): Security error: The parameters passed to the constructor of the authenticator are potentially unsafe");
668        }
669
670        $string=$this->_row['network_authenticator_params'];
671         
672        $params = explode(',', $string);
673        for ($i = 0; $i < count($params); $i++) {
674            $nquotes = substr_count($params[$i], '\'');
675            if ($nquotes %2 == 1) {
676                for ($j = $i+1; $j < count($params); $j++) {
677                    if (substr_count($params[$j], '\'') > 0) {
678                        array_splice($params, $i, $j-$i+1,
679                        implode(',', array_slice($params, $i, $j-$i+1)));
680                        break;
681                    }
682                }
683            }
684            if ($nquotes > 0) {
685                $qstr =& $params[$i];
686                $qstr = substr_replace($qstr, '', strpos($qstr, '\''), 1);
687                $qstr = substr_replace($qstr, '', strrpos($qstr, '\''), 1);
688            }
689        }
690        return call_user_func_array(array (new ReflectionClass($this->_row['network_authenticator_class']), 'newInstance'), $params);
691
692    }
693
694    /**
695     * Get the list of available Authenticators on the system
696     *
697     * @return array An array of class names
698
699     */
700    public static function getAvailableAuthenticators()
701    {
702        // Init values
703        $authenticators = array ();
704        $useCache = false;
705        $cachedData = null;
706
707        // Create new cache object with a lifetime of one week
708        $cache = new Cache("AuthenticatorClasses", "ClassFileCaches", 604800);
709
710        // Check if caching has been enabled.
711        if ($cache->isCachingEnabled) {
712            $cachedData = $cache->getCachedData("mixed");
713
714            if ($cachedData) {
715                // Return cached data.
716                $useCache = true;
717                $authenticators = $cachedData;
718            }
719        }
720
721        if (!$useCache) {
722            $dir = WIFIDOG_ABS_FILE_PATH."classes/Authenticators";
723            $dirHandle = @ opendir($dir);
724
725            if ($dirHandle) {
726                // Loop over the directory
727                while (false !== ($filename = readdir($dirHandle))) {
728                    // Loop through sub-directories of Content
729                    if ($filename != '.' && $filename != '..') {
730                        $matches = null;
731
732                        if (preg_match("/^(.*)\.php$/", $filename, $matches) > 0) {
733                            // Only add files containing a corresponding Authenticator class
734                            if (is_file("{$dir}/{$matches[0]}")) {
735                                $authenticators[] = $matches[1];
736                            }
737                        }
738                    }
739                }
740
741                closedir($dirHandle);
742            }
743            else {
744                throw new Exception(_('Unable to open directory ').$dir);
745            }
746
747            // Sort the result array
748            sort($authenticators);
749
750            // Check if caching has been enabled.
751            if ($cache->isCachingEnabled) {
752                // Save results into cache, because it wasn't saved into cache before.
753                $cache->saveCachedData($authenticators, "mixed");
754            }
755        }
756
757        return $authenticators;
758    }
759
760    /**
761     * Get an interface to pick an Authenticator
762     *
763     * @param string $user_prefix                A identifier provided by the
764     *                                           programmer to recognise it's
765     *                                           generated html form
766     * @param string $pre_selected_authenticator The Authenticator to be
767     *                                           pre-selected in the form object
768     *
769     * @return string HTML markup
770
771     */
772    public static function getSelectAuthenticator($user_prefix, $pre_selected_authenticator = null)
773    {
774
775        $db = AbstractDb::getObject();
776
777        // Init values
778        $authenticators = array ();
779
780        foreach (self :: getAvailableAuthenticators() as $authenticator) {
781            $authenticators[] = array ($authenticator, $authenticator);
782        }
783
784        $name = $user_prefix;
785
786        if ($pre_selected_authenticator) {
787            $selectedID = $pre_selected_authenticator;
788        }
789        else {
790            $selectedID = null;
791        }
792
793        $html = FormSelectGenerator :: generateFromArray($authenticators, $selectedID, $name, null, false);
794
795        return $html;
796    }
797
798    /**
799     * Is the network the default network?
800     *
801     * @return bool True or false
802     *
803     * @access public
804     */
805    public function isDefaultNetwork()
806    {
807        (self::getDefaultNetwork()->getId() == $this->getId()) ? $retval = true : $retval = false;
808        return $retval;
809    }
810
811    /**
812     * Retreives the network's validation grace period
813     *
814     * @return int Network's validation grace period in seconds
815     *
816     * @access public
817     */
818    public function getValidationGraceTime()
819    {
820        return $this->_row['validation_grace_time_seconds'];
821    }
822
823    /**
824     * Set the network's validation grace period in seconds.
825     *
826     * A new user is granted Internet access for this period check his email
827     * and validate his account.
828     *
829     * @param int $value The new value
830     *
831     * @return bool True on success, false on failure
832     *
833     * @access public
834     */
835    public function setValidationGraceTime($value)
836    {
837        // Init values
838        $retval = true;
839
840        if ($value != $this->getValidationGraceTime()) {
841            $db = AbstractDb::getObject();
842            $value = $db->escapeString($value);
843            $retval = $db->execSqlUpdate("UPDATE networks SET validation_grace_time = '{$value} seconds' WHERE network_id = '{$this->getId()}'", false);
844            $this->refresh();
845        }
846
847        return $retval;
848    }
849
850    /**
851     * Retreives the FROM address of the validation email
852     *
853     * @return string A string
854     *
855     * @access public
856     */
857    public function getValidationEmailFromAddress()
858    {
859        return $this->_row['validation_email_from_address'];
860    }
861
862    /**
863     * Set the FROM address of the validation email
864     *
865     * @param string $value The new value
866     *
867     * @return bool True on success, false on failure
868     *
869     * @access public
870     */
871    public function setValidationEmailFromAddress($value)
872    {
873        // Init values
874        $retval = true;
875
876        if ($value != $this->getValidationEmailFromAddress()) {
877            $db = AbstractDb::getObject();
878            $value = $db->escapeString($value);
879            $retval = $db->execSqlUpdate("UPDATE networks SET validation_email_from_address = '{$value}' WHERE network_id = '{$this->getId()}'", false);
880            $this->refresh();
881        }
882
883        return $retval;
884    }
885
886    /**
887     * Can an account be connected more than once at the same time?
888     *
889     * @return bool True or false
890     *
891     * @access public
892     */
893    public function getMultipleLoginAllowed()
894    {
895        return ($this->_row['allow_multiple_login'] == 't') ? true : false;
896    }
897
898    /**
899     * Set if a account be connected more than once at the same time
900     *
901     * @param bool $value The new value, true or false
902     *
903     * @return bool true on success, false on failure
904     *
905     * @access public
906     */
907    public function setMultipleLoginAllowed($value)
908    {
909        // Init values
910        $retval = true;
911
912        if ($value != $this->getMultipleLoginAllowed()) {
913            $db = AbstractDb::getObject();
914            $value ? $value = 'TRUE' : $value = 'FALSE';
915            $retval = $db->execSqlUpdate("UPDATE networks SET allow_multiple_login = {$value} WHERE network_id = '{$this->getId()}'", false);
916            $this->refresh();
917        }
918
919        return $retval;
920    }
921
922    /**
923     * Are nodes allowed to be set as splash-only (no login)?
924     *
925     * @return bool True or false
926     *
927     * @access public
928     */
929    public function getSplashOnlyNodesAllowed()
930    {
931        return (($this->_row['allow_splash_only_nodes'] == 't') ? true : false);
932    }
933
934    /**
935     * Set if nodes are allowed to be set as splash-only (no login)
936     *
937     * @param bool $value The new value, true or false
938     *
939     * @return bool True on success, false on failure
940     *
941     * @access public
942     */
943    public function setSplashOnlyNodesAllowed($value)
944    {
945        // Init values
946        $retval = true;
947
948        if ($value != $this->getSplashOnlyNodesAllowed()) {
949            $db = AbstractDb::getObject();
950            $value ? $value = 'TRUE' : $value = 'FALSE';
951            $retval = $db->execSqlUpdate("UPDATE networks SET allow_splash_only_nodes = {$value} WHERE network_id = '{$this->getId()}'", false);
952            $this->refresh();
953        }
954
955        return $retval;
956    }
957
958    /**
959     * Get a GisPoint object
960     *
961     * @return object GisPoint object
962     */
963    public function getGisLocation()
964    {
965        return new GisPoint($this->_row['gmaps_initial_latitude'], $this->_row['gmaps_initial_longitude'], $this->_row['gmaps_initial_zoom_level']);
966    }
967
968    /**
969     * Set the network's GisPoint object
970     *
971     * @param $value The new GisPoint object
972     *
973     * @return bool True on success, false on failure
974     */
975    public function setGisLocation($pt)
976    {
977        $retval=false;
978        $db = AbstractDb::getObject();
979
980        if (!empty ($pt)) {
981            $lat = $db->escapeString($pt->getLatitude());
982            $long = $db->escapeString($pt->getLongitude());
983            $alt = $db->escapeString($pt->getAltitude());
984
985            if (!empty ($lat) && !empty ($long) && !empty ($alt)) {
986                $db->execSqlUpdate("UPDATE networks SET gmaps_initial_latitude = $lat, gmaps_initial_longitude = $long, gmaps_initial_zoom_level = $alt WHERE network_id = '{$this->getId()}'");
987                $retval=true;
988            }
989            else {
990                $db->execSqlUpdate("UPDATE networks SET gmaps_initial_latitude = NULL, gmaps_initial_longitude = NULL, gmaps_initial_zoom_level = NULL WHERE network_id = '{$this->getId()}'");
991            }
992            $this->refresh();
993        }
994        return $retval;
995    }
996
997    /**
998     * Retreives the default Google maps type
999     *
1000     * @return string Default Google maps type
1001     */
1002    public function getGisMapType()
1003    {
1004        return $this->_row['gmaps_map_type'];
1005    }
1006
1007    /**
1008     * Set the network's default Google maps type
1009     *
1010     * @param $value The new default Google maps type
1011     *
1012     * @return bool True on success, false on failure
1013     */
1014    public function setGisMapType($value)
1015    {
1016
1017        $db = AbstractDb::getObject();
1018
1019        // Init values
1020        $retval = true;
1021
1022        if ($value != $this->getGisMapType()) {
1023            $value = $db->escapeString($value);
1024            $retval = $db->execSqlUpdate("UPDATE networks SET gmaps_map_type = '{$value}' WHERE network_id = '{$this->getId()}'", false);
1025            $this->refresh();
1026        }
1027        return $retval;
1028    }
1029
1030    /**
1031     * Get an interface to pick a Google maps type
1032     *
1033     * @param string $user_prefix           A identifier provided by the
1034     *                                      programmer to recognise it's
1035     *                                      generated html form
1036     * @param string $pre_selected_map_type The Google map type to be
1037     *                                      pre-selected in the form object
1038     *
1039     * @return string HTML markup
1040
1041     */
1042    public static function getSelectGisMapType($user_prefix, $pre_selected_map_type = "G_NORMAL_MAP")
1043    {
1044
1045        $db = AbstractDb::getObject();
1046
1047        // Init values
1048        $map_types = array (array ("G_NORMAL_MAP", _("Map")), array ("G_SATELLITE_MAP", _("Satellite")), array ("G_HYBRID_MAP", _("Hybrid")));
1049
1050        $name = $user_prefix;
1051
1052        if ($pre_selected_map_type) {
1053            $selectedID = $pre_selected_map_type;
1054        }
1055        else {
1056            $selectedID = null;
1057        }
1058
1059        $html = FormSelectGenerator :: generateFromArray($map_types, $selectedID, $name, null, false);
1060
1061        return $html;
1062    }
1063
1064    /**
1065     * Get's the splash-only user.
1066     *
1067     * This is the user that people logged-in at a splash-only hotspot will
1068     * show up as.  This user always has multiple-login capabilities.
1069     *
1070     * @param string $username The username of the user
1071     * @param string $account_origin The account origin
1072     *
1073     * @return object A User object
1074     *
1075     * @access public
1076     */
1077    public function getSplashOnlyUser()
1078    {
1079        $username = 'SPLASH_ONLY_USER';
1080        if(!empty($this->splashOnlyUser)) {
1081            $user = $this->splashOnlyUser;
1082        }
1083        else
1084        {
1085            $user = User :: getUserByUsernameAndOrigin($username, $this);
1086            if (!$user) {
1087                $user = User :: createUser(get_guid(), $username, $this, '', '');
1088                $user->setAccountStatus(ACCOUNT_STATUS_ALLOWED);
1089            }
1090            $this->splashOnlyUser = $user;
1091        }
1092        return $user;
1093    }
1094
1095    /**
1096     * Find out the total number of users in this networks's database
1097     *
1098     * @return int Number of users
1099     */
1100    public function getNumUsers()
1101    {
1102
1103        $db = AbstractDb::getObject();
1104
1105        // Init values
1106        $retval = 0;
1107        $row = null;
1108        $useCache = false;
1109        $cachedData = null;
1110
1111        // Create new cache objects (valid for 1 minute)
1112        $cache = new Cache('network_'.$this->_id.'_num_users', $this->_id, 60);
1113
1114        // Check if caching has been enabled.
1115        if ($cache->isCachingEnabled) {
1116            $cachedData = $cache->getCachedData();
1117
1118            if ($cachedData) {
1119                // Return cached data.
1120                $useCache = true;
1121                $retval = $cachedData;
1122            }
1123        }
1124
1125        if (!$useCache) {
1126            // Get number of users
1127            $network_id = $db->escapeString($this->_id);
1128            $db->execSqlUniqueRes("SELECT COUNT(user_id) FROM users WHERE account_origin='$network_id'", $row, false);
1129
1130            // String has been found
1131            $retval = $row['count'];
1132
1133            // Check if caching has been enabled.
1134            if ($cache->isCachingEnabled) {
1135                // Save data into cache, because it wasn't saved into cache before.
1136                $cache->saveCachedData($retval);
1137            }
1138        }
1139
1140        return $retval;
1141    }
1142
1143    /**
1144     * Find out how many users are valid in this networks's database
1145     *
1146     * @return int Number of valid users
1147     */
1148    public function getNumValidUsers()
1149    {
1150
1151        $db = AbstractDb::getObject();
1152
1153        // Init values
1154        $retval = 0;
1155        $row = null;
1156        $useCache = false;
1157        $cachedData = null;
1158
1159        // Create new cache objects (valid for 1 minute)
1160        $cache = new Cache('network_'.$this->_id.'_num_valid_users', $this->_id, 60);
1161
1162        // Check if caching has been enabled.
1163        if ($cache->isCachingEnabled) {
1164            $cachedData = $cache->getCachedData();
1165
1166            if ($cachedData) {
1167                // Return cached data.
1168                $useCache = true;
1169                $retval = $cachedData;
1170            }
1171        }
1172
1173        if (!$useCache) {
1174            // Get number of valid users
1175            $network_id = $db->escapeString($this->_id);
1176            $db->execSqlUniqueRes("SELECT COUNT(user_id) FROM users WHERE account_status = ".ACCOUNT_STATUS_ALLOWED." AND account_origin='$network_id'", $row, false);
1177            // String has been found
1178            $retval = $row['count'];
1179
1180            // Check if caching has been enabled.
1181            if ($cache->isCachingEnabled) {
1182                // Save data into cache, because it wasn't saved into cache before.
1183                $cache->saveCachedData($retval);
1184            }
1185        }
1186
1187        return $retval;
1188    }
1189
1190    /**
1191     * Find out how many users are connected on the entire network
1192     * Counts every user account connected (once for every account), except the splash-only user + every mac adresses connecting as the splash-only user
1193     * @return int Number of online users
1194     */
1195    public function getNumOnlineUsers()
1196    {
1197
1198        $db = AbstractDb::getObject();
1199
1200        // Init values
1201        $retval = 0;
1202        $row = null;
1203        $useCache = false;
1204        $cachedData = null;
1205
1206        // Create new cache objects (valid for 1 minute)
1207        $cache = new Cache('network_'.$this->_id.'_num_online_users', $this->_id, 60);
1208
1209        // Check if caching has been enabled.
1210        if ($cache->isCachingEnabled) {
1211            $cachedData = $cache->getCachedData();
1212
1213            if ($cachedData) {
1214                // Return cached data.
1215                $useCache = true;
1216                $retval = $cachedData;
1217            }
1218        }
1219
1220        if (!$useCache) {
1221            // Get number of online users
1222            $network_id = $db->escapeString($this->_id);
1223            $splashOnlyUserId = $this->getSplashOnlyUser()->getId();
1224            $sql = "SELECT ((SELECT COUNT(DISTINCT users.user_id) as count FROM users,connections JOIN tokens USING (token_id) NATURAL JOIN nodes JOIN networks ON (nodes.network_id=networks.network_id AND networks.network_id='$network_id') WHERE tokens.token_status='".TOKEN_INUSE."' AND users.user_id=connections.user_id AND users.user_id!='{$splashOnlyUserId}') + (SELECT COUNT(DISTINCT connections.user_mac) as count FROM users,connections JOIN tokens USING (token_id) NATURAL JOIN nodes JOIN networks ON (nodes.network_id=networks.network_id AND networks.network_id='$network_id') WHERE tokens.token_status='".TOKEN_INUSE."' AND users.user_id=connections.user_id AND users.user_id='{$splashOnlyUserId}')) AS count";
1225            $db->execSqlUniqueRes($sql, $row, false);
1226
1227            $retval = $row['count'];
1228
1229            // Check if caching has been enabled.
1230            if ($cache->isCachingEnabled) {
1231                // Save data into cache, because it wasn't saved into cache before.
1232                $cache->saveCachedData($retval);
1233            }
1234        }
1235
1236        return $retval;
1237    }
1238
1239    /**
1240     * Find out how many nodes are registered in this networks's database
1241     *
1242     * @return int Number of nodes
1243     */
1244    public function getNumNodes()
1245    {
1246
1247        $db = AbstractDb::getObject();
1248
1249        // Init values
1250        $retval = 0;
1251        $row = null;
1252        $useCache = false;
1253        $cachedData = null;
1254
1255        // Create new cache objects (valid for 5 minutes)
1256        $cache = new Cache('network_'.$this->_id.'_num_nodes', $this->_id, 300);
1257
1258        // Check if caching has been enabled.
1259        if ($cache->isCachingEnabled) {
1260            $cachedData = $cache->getCachedData();
1261
1262            if ($cachedData) {
1263                // Return cached data.
1264                $useCache = true;
1265                $retval = $cachedData;
1266            }
1267        }
1268
1269        if (!$useCache) {
1270            // Get number of nodes
1271            $network_id = $db->escapeString($this->_id);
1272            $db->execSqlUniqueRes("SELECT COUNT(node_id) FROM nodes WHERE network_id = '$network_id'", $row, false);
1273
1274            // String has been found
1275            $retval = $row['count'];
1276
1277            // Check if caching has been enabled.
1278            if ($cache->isCachingEnabled) {
1279                // Save data into cache, because it wasn't saved into cache before.
1280                $cache->saveCachedData($retval);
1281            }
1282        }
1283
1284        return $retval;
1285    }
1286
1287    /**
1288     * Find out how many nodes are deployed in this networks's database
1289     *
1290     * @return int Number of deployed nodes
1291     */
1292    public function getNumDeployedNodes()
1293    {
1294
1295        $db = AbstractDb::getObject();
1296
1297        // Init values
1298        $retval = 0;
1299        $row = null;
1300        $useCache = false;
1301        $cachedData = null;
1302
1303        // Create new cache objects (valid for 5 minutes)
1304        $cache = new Cache('network_'.$this->_id.'_num_deployed_nodes', $this->_id, 300);
1305
1306        // Check if caching has been enabled.
1307        if ($cache->isCachingEnabled) {
1308            $cachedData = $cache->getCachedData();
1309
1310            if ($cachedData) {
1311                // Return cached data.
1312                $useCache = true;
1313                $retval = $cachedData;
1314            }
1315        }
1316
1317        if (!$useCache) {
1318            // Get number of deployed nodes
1319            $network_id = $db->escapeString($this->_id);
1320            $db->execSqlUniqueRes("SELECT COUNT(node_id) FROM nodes WHERE network_id = '$network_id' AND (node_deployment_status = 'DEPLOYED' OR node_deployment_status = 'NON_WIFIDOG_NODE')", $row, false);
1321
1322            // String has been found
1323            $retval = $row['count'];
1324
1325            // Check if caching has been enabled.
1326            if ($cache->isCachingEnabled) {
1327                // Save data into cache, because it wasn't saved into cache before.
1328                $cache->saveCachedData($retval);
1329            }
1330        }
1331
1332        return $retval;
1333    }
1334
1335    /**
1336     * Find out how many deployed nodes are online in this networks's database
1337     *
1338     * @param bool $nonMonitoredOnly Return number of non-monitored nodes only
1339     *
1340     * @return int Number of deployed nodes which are online
1341     */
1342    public function getNumOnlineNodes($nonMonitoredOnly = false)
1343    {
1344
1345        $db = AbstractDb::getObject();
1346
1347        // Init values
1348        $retval = 0;
1349        $row = null;
1350        $useCache = false;
1351        $cachedData = null;
1352
1353        // Create new cache objects (valid for 5 minutes)
1354        if ($nonMonitoredOnly) {
1355            $cache = new Cache('network_'.$this->_id.'_num_online_nodes_non_monitored', $this->_id, 300);
1356        } else {
1357            $cache = new Cache('network_'.$this->_id.'_num_online_nodes', $this->_id, 300);
1358        }
1359
1360        // Check if caching has been enabled.
1361        if ($cache->isCachingEnabled) {
1362            $cachedData = $cache->getCachedData();
1363
1364            if ($cachedData) {
1365                // Return cached data.
1366                $useCache = true;
1367                $retval = $cachedData;
1368            }
1369        }
1370
1371        if (!$useCache) {
1372            // Get number of online nodes
1373            $network_id = $db->escapeString($this->_id);
1374
1375            if ($nonMonitoredOnly) {
1376                $db->execSqlUniqueRes("SELECT COUNT(node_id) FROM nodes WHERE network_id = '$network_id' AND node_deployment_status = 'NON_WIFIDOG_NODE' AND ((CURRENT_TIMESTAMP-last_heartbeat_timestamp) >= interval '5 minutes')", $row, false);
1377            } else {
1378                $db->execSqlUniqueRes("SELECT COUNT(node_id) FROM nodes WHERE network_id = '$network_id' AND (node_deployment_status = 'DEPLOYED' OR node_deployment_status = 'NON_WIFIDOG_NODE') AND ((CURRENT_TIMESTAMP-last_heartbeat_timestamp) < interval '5 minutes')", $row, false);
1379            }
1380
1381            // String has been found
1382            $retval = $row['count'];
1383
1384            // Check if caching has been enabled.
1385            if ($cache->isCachingEnabled) {
1386                // Save data into cache, because it wasn't saved into cache before.
1387                $cache->saveCachedData($retval);
1388            }
1389        }
1390
1391        return $retval;
1392    }
1393
1394    /**
1395     * Are nodes allowed to redirect users to an arbitrary web page instead of
1396     * the portal?
1397     *
1398     * @return bool True or false
1399     *
1400     * @access public
1401     */
1402    public function getCustomPortalRedirectAllowed()
1403    {
1404        return (($this->_row['allow_custom_portal_redirect'] == 't') ? true : false);
1405    }
1406
1407    /**
1408     * Set if nodes are allowed to redirect users to an arbitrary web page
1409     * instead of the portal?
1410     *
1411     * @param bool $value The new value, true or false
1412     *
1413     * @return bool True on success, false on failure
1414     *
1415     * @access public
1416     */
1417    public function setCustomPortalRedirectAllowed($value)
1418    {
1419        // Init values
1420        $retval = true;
1421
1422        if ($value != $this->getCustomPortalRedirectAllowed()) {
1423            $db = AbstractDb::getObject();
1424            $value ? $value = 'TRUE' : $value = 'FALSE';
1425            $retval = $db->execSqlUpdate("UPDATE networks SET allow_custom_portal_redirect = {$value} WHERE network_id = '{$this->getId()}'", false);
1426            $this->refresh();
1427        }
1428
1429        return $retval;
1430    }
1431
1432    /**
1433     * Are nodes allowed to redirect users to the original requested web page instead of
1434     * the portal?
1435     *
1436     * @return bool True or false
1437     *
1438     * @access public
1439     */
1440    public function getPortalOriginalUrlAllowed()
1441    {
1442        return (($this->_row['allow_original_url_redirect'] == 't') ? true : false);
1443    }
1444
1445    /**
1446     * Set if nodes are allowed to redirect users to the original requested web page
1447     * instead of the portal?
1448     *
1449     * @param bool $value The new value, true or false
1450     *
1451     * @return bool True on success, false on failure
1452     *
1453     * @access public
1454     */
1455    public function setPortalOriginalUrlAllowed($value)
1456    {
1457        // Init values
1458        $retval = true;
1459
1460        if ($value != $this->getPortalOriginalUrlAllowed()) {
1461            $db = AbstractDb::getObject();
1462            $value ? $value = 'TRUE' : $value = 'FALSE';
1463            $retval = $db->execSqlUpdate("UPDATE networks SET allow_original_url_redirect = {$value} WHERE network_id = '{$this->getId()}'", false);
1464            $this->refresh();
1465        }
1466
1467        return $retval;
1468    }
1469
1470
1471    /** The length of the window during which the user must not have exceeded the limits below.
1472     *
1473     * @return string Interval as returned by postgresql
1474     */
1475    public function getConnectionLimitWindow()
1476    {
1477        return $this->_row['connection_limit_window'];
1478    }
1479
1480    /**
1481     * Set the network's creation date
1482     *
1483     * @param string $value The new creation date
1484     *
1485     * @return bool True on success, false on failure
1486     */
1487    public function setConnectionLimitWindow($value)
1488    {
1489        $db = AbstractDb::getObject();
1490        // Init values
1491        $retVal = true;
1492
1493        if ($value != $this->getConnectionLimitWindow()) {
1494            $value?$value_sql="'".$db->escapeString($value)."'":$value_sql="NULL";
1495            $retVal = $db->execSqlUpdate("UPDATE networks SET connection_limit_window = $value_sql WHERE network_id = '{$this->getId()}'", false);
1496            $this->refresh();
1497        }
1498        return $retVal;
1499    }
1500
1501    /** Maximum data transfer during the abuse control window, in bytes
1502     *
1503     * @return integer Number of bytes
1504     */
1505    public function getConnectionLimitNetworkMaxTotalBytes()
1506    {
1507        return $this->_row['connection_limit_network_max_total_bytes'];
1508    }
1509
1510    /**
1511     * Maximum data transfer during the abuse control window, in bytes
1512     *
1513     * @param $value integer Number of bytes
1514     *
1515     * @return bool True on success, false on failure
1516     */
1517    public function setConnectionLimitNetworkMaxTotalBytes($value)
1518    {
1519        $db = AbstractDb::getObject();
1520        // Init values
1521        $retVal = true;
1522
1523        if ($value != $this->getConnectionLimitNetworkMaxTotalBytes()) {
1524            $value?$value_sql="'".$db->escapeString($value)."'":$value_sql="NULL";
1525            $retVal = $db->execSqlUpdate("UPDATE networks SET connection_limit_network_max_total_bytes = $value_sql WHERE network_id = '{$this->getId()}'", false);
1526            $this->refresh();
1527        }
1528        return $retVal;
1529    }
1530
1531    /** Maximum connection duration during the abuse control window
1532     *
1533     * @return string Interval as returned by postgresql
1534     */
1535    public function getConnectionLimitNetworkMaxDuration()
1536    {
1537        return $this->_row['connection_limit_network_max_usage_duration'];
1538    }
1539
1540    /** Maximum connection duration during the abuse control window
1541     *
1542     * @param string $value The new creation date
1543     *
1544     * @return bool True on success, false on failure
1545     */
1546    public function setConnectionLimitNetworkMaxDuration($value)
1547    {
1548        $db = AbstractDb::getObject();
1549        // Init values
1550        $retVal = true;
1551
1552        if ($value != $this->getConnectionLimitNetworkMaxDuration()) {
1553            $value?$value_sql="'".$db->escapeString($value)."'":$value_sql="NULL";
1554            $retVal = $db->execSqlUpdate("UPDATE networks SET connection_limit_network_max_usage_duration = $value_sql WHERE network_id = '{$this->getId()}'", false);
1555            $this->refresh();
1556        }
1557        return $retVal;
1558    }
1559
1560    /** Maximum data transfer during the abuse control window, in bytes
1561     *
1562     * @return integer Number of bytes
1563     */
1564    public function getConnectionLimitNodeMaxTotalBytes()
1565    {
1566        return $this->_row['connection_limit_node_max_total_bytes'];
1567    }
1568
1569    /**
1570     * Maximum data transfer during the abuse control window, in bytes
1571     *
1572     * @param $value integer Number of bytes
1573     *
1574     * @return bool True on success, false on failure
1575     */
1576    public function setConnectionLimitNodeMaxTotalBytes($value)
1577    {
1578        $db = AbstractDb::getObject();
1579        // Init values
1580        $retVal = true;
1581
1582        if ($value != $this->getConnectionLimitNodeMaxTotalBytes()) {
1583            $value?$value_sql="'".$db->escapeString($value)."'":$value_sql="NULL";
1584            $retVal = $db->execSqlUpdate("UPDATE networks SET connection_limit_node_max_total_bytes = $value_sql WHERE network_id = '{$this->getId()}'", false);
1585            $this->refresh();
1586        }
1587        return $retVal;
1588    }
1589
1590    /** Maximum connection duration during the abuse control window
1591     *
1592     * @return string Interval as returned by postgresql
1593     */
1594    public function getConnectionLimitNodeMaxDuration()
1595    {
1596        return $this->_row['connection_limit_node_max_usage_duration'];
1597    }
1598
1599    /** Maximum connection duration during the abuse control window
1600     *
1601     * @param string $value The new creation date
1602     *
1603     * @return bool True on success, false on failure
1604     */
1605    public function setConnectionLimitNodeMaxDuration($value)
1606    {
1607        $db = AbstractDb::getObject();
1608        // Init values
1609        $retVal = true;
1610
1611        if ($value != $this->getConnectionLimitNodeMaxDuration()) {
1612            $value?$value_sql="'".$db->escapeString($value)."'":$value_sql="NULL";
1613            $retVal = $db->execSqlUpdate("UPDATE networks SET connection_limit_node_max_usage_duration = $value_sql WHERE network_id = '{$this->getId()}'", false);
1614            $this->refresh();
1615        }
1616        return $retVal;
1617    }
1618   
1619          /** Are usernames on this network case sensitive or not
1620     *
1621     * @return bool true or false
1622     */
1623    public function getUsernamesCaseSensitive()
1624    {
1625        return (($this->_row['usernames_case_sensitive'] == 't') ? true : false);
1626    }
1627
1628    /** Are usernames on this network case sensitive or not
1629     * If set to false, we need to verify if some users have name-clash and propose actions
1630     *
1631     * @param string $value The new creation date
1632     *
1633     * @return bool True on success, false on failure
1634     */
1635    public function setUsernamesCaseSensitive($value)
1636    {
1637        // Init values
1638        $retval = true;
1639
1640        if ($value != $this->getUsernamesCaseSensitive()) {
1641            $db = AbstractDb::getObject();
1642            // Verify if usernames differing by case exists
1643            if (!$value) {
1644                $sql = "Select username, email from users where
1645                    lower(username) in (Select lower(username) as uname from users where account_origin = '{$this->getId()}' group by lower(username) having count(user_id) > 1)
1646                    or lower(email) in (Select lower(email) from users where account_origin = '{$this->getId()}' group by lower(email) having count(user_id) > 1) order by username";
1647                if (!$db->execSql($sql, $duplicates)) 
1648                    $retval = false;
1649                if (!empty($duplicates)) {
1650                    $duplicatenames = array();
1651                    foreach($duplicates as $duplicate) $duplicatenames[] = "{$duplicate['username']} ({$duplicate['email']})";
1652                    $this->errorMsg = _("You cannot change the case sensitivity of this network because some users would have duplicate names or emails.  Some action must be performed before.<br/>Here is a list of duplicate usernames: " . implode(', ', $duplicatenames));
1653                    $retval = false;
1654                }
1655            }
1656            if ($retval) {
1657                $value ? $value = 'TRUE' : $value = 'FALSE';
1658                $retval = $db->execSqlUpdate("UPDATE networks SET usernames_case_sensitive = {$value} WHERE network_id = '{$this->getId()}'", false);
1659                $this->refresh();
1660            }
1661        }
1662
1663        return $retval;
1664    }
1665
1666
1667    /**
1668     * Retreives the admin interface of this object
1669     *
1670     * @return string The HTML fragment for this interface
1671     */
1672    public function getAdminUI()
1673    {
1674        Security::requirePermission(Permission::P('NETWORK_PERM_EDIT_NETWORK_CONFIG'), $this);
1675        require_once('classes/InterfaceElements.php');
1676        // Init values
1677        $html = '';
1678       
1679        /*
1680         * Verify if an error message was registered before outputting the form
1681         */
1682        if (isset($this->errorMsg)) {
1683             $html .= "<div class='errormsg'>" . $this->errorMsg . "</div>";
1684        }
1685
1686        /*
1687         * Begin with admin interface
1688         */
1689        $html .= "<fieldset class='admin_container ".get_class($this)."'>\n";
1690        $html .= "<legend>"._("Network management")."</legend>\n";
1691        $html .= "<ul class='admin_element_list'>\n";
1692
1693        /*
1694         * Content management
1695         */
1696       /* $title = _("Network content");
1697        $name = "network_".$this->_id."_content";
1698        $data = Content::getLinkedContentUI($name, "network_has_content", "network_id", $this->_id, $display_page = "portal");
1699        $html .= InterfaceElements::generateAdminSectionContainer("network_content", $title, $data);*/
1700       
1701        $html .= parent::getContentAdminUI();
1702
1703        /*
1704         * Network information
1705         */
1706        $html_network_information = array();
1707
1708        // network_id
1709        $title = _("Network ID");
1710        $data = htmlspecialchars($this->getId(), ENT_QUOTES);
1711        $html_network_information[] = InterfaceElements::generateAdminSectionContainer("network_id", $title, $data);
1712
1713        // name
1714        $title = _("Network name");
1715        $data = InterfaceElements::generateInputText("network_" . $this->getId() . "_name", $this->getName(), "network_name_input");
1716        $html_network_information[] = InterfaceElements::generateAdminSectionContainer("network_name", $title, $data);
1717
1718        // creation_date
1719        $title = _("Network creation date");
1720        $data = DateTimeWD::getSelectDateTimeUI(new DateTimeWD($this->getCreationDate()), "network_" . $this->getId() . "_creation_date", DateTimeWD::INTERFACE_DATETIME_FIELD, "network_creation_date_input");
1721        $html_network_information[] = InterfaceElements::generateAdminSectionContainer("network_creation_date", $title, $data);
1722
1723        // homepage_url
1724        $title = _("Network's web site");
1725        $data = InterfaceElements::generateInputText("network_" . $this->getId() . "_homepage_url", $this->getWebSiteURL(), "network_homepage_url_input");
1726        $html_network_information[] = InterfaceElements::generateAdminSectionContainer("network_homepage_url", $title, $data);
1727
1728        // tech_support_email
1729        $title = _("Technical support email");
1730        $data = InterfaceElements::generateInputText("network_" . $this->getId() . "_tech_support_email", $this->getTechSupportEmail(), "network_tech_support_email_input");
1731        $html_network_information[] = InterfaceElements::generateAdminSectionContainer("network_tech_support_email", $title, $data);
1732
1733        // Build section
1734        $html .= InterfaceElements::generateAdminSectionContainer("network_information", _("Information about the network"), implode(null, $html_network_information));
1735
1736        /*
1737         * Network authentication
1738         */
1739        $html_network_authentication = array();
1740
1741        //  network_authenticator_class
1742        $title = _("Network authenticator class");
1743        $help = _("The subclass of Authenticator to be used for user authentication. Example: AuthenticatorRadius");
1744        $name = "network_" . $this->getId() . "_network_authenticator_class";
1745        $value = htmlspecialchars($this->getAuthenticatorClassName(), ENT_QUOTES);
1746        $data = $this->getSelectAuthenticator($name, $value);
1747        $html_network_authentication[] = InterfaceElements::generateAdminSectionContainer("network_network_authenticator_class", $title, $data, $help);
1748
1749        //  network_authenticator_params
1750        $title = _("Authenticator parameters");
1751        $help = _("The explicit parameters to be passed to the authenticator. You MUST read the constructor documentation of your desired authenticator class (in wifidog/classes/Authenticators/) BEFORE you start playing with this.  Example: 'my_network_id', '192.168.0.11', 1812, 1813, 'secret_key', 'CHAP_MD5'");
1752        $data = InterfaceElements::generateInputText("network_" . $this->getId() . "_network_authenticator_params", $this->getAuthenticatorConstructorParams(), "network_network_authenticator_params_input");
1753        $html_network_authentication[] = InterfaceElements::generateAdminSectionContainer("network_network_authenticator_params", $title, $data, $help);
1754
1755        // Build section
1756        $html .= InterfaceElements::generateAdminSectionContainer("network_authentication", _("Network Authentication"), implode(null, $html_network_authentication));
1757
1758        /*
1759         * Network properties
1760         */
1761        $html_network_properties = array();
1762
1763        //  theme_pack
1764        $title = _("Selected theme pack for this network");
1765        $data = ThemePack::getSelectUI("network_" . $this->getId() . "_theme_pack", $this->getThemePack());
1766        $html_network_properties[] = InterfaceElements::generateAdminSectionContainer("network_theme_pack", $title, $data);
1767     
1768        // Build section
1769        $html .= InterfaceElements::generateAdminSectionContainer("network_properties", _("Network properties"), implode(null, $html_network_properties));
1770
1771        /*
1772         * Network's node properties
1773         */
1774        $html_network_node_properties = array();
1775
1776        //  allow_splash_only_nodes
1777        $title = _("Splash-only nodes");
1778        $help = _("Are nodes allowed to be set as splash-only (no login)?");
1779        $data = InterfaceElements::generateInputCheckbox("network_" . $this->getId() . "_allow_splash_only_nodes", "", _("Yes"), $this->getSplashOnlyNodesAllowed(), "network_allow_splash_only_nodes_radio");
1780        $html_network_node_properties[] = InterfaceElements::generateAdminSectionContainer("network_allow_splash_only_nodes", $title, $data, $help);
1781
1782        //  allow_custom_portal_redirect
1783        $title = _("Portal page redirection");
1784        $help = _("Are nodes allowed to redirect users to an arbitrary web page instead of the portal?");
1785        $data = InterfaceElements::generateInputCheckbox("network_" . $this->getId() . "_allow_custom_portal_redirect", "", _("Yes"), $this->getCustomPortalRedirectAllowed(), "network_allow_custom_portal_redirect_radio");
1786        $html_network_node_properties[] = InterfaceElements::generateAdminSectionContainer("network_allow_custom_portal_redirect", $title, $data, $help);
1787
1788        //  allow_original_URL_redirect
1789        $title = _("Original URL redirection");
1790        $help = _("Are nodes allowed to redirect users to the web page they originally requested instead of the portal?");
1791        $data = InterfaceElements::generateInputCheckbox("network_" . $this->getId() . "_allow_original_URL_redirect", "", _("Yes"), $this->getPortalOriginalUrlAllowed(), "network_allow_original_URL_redirect_radio");
1792        $html_network_node_properties[] = InterfaceElements::generateAdminSectionContainer("network_allow_original_URL_redirect", $title, $data, $help);   
1793
1794        // Build section
1795        $html .= InterfaceElements::generateAdminSectionContainer("network_node_properties", _("Network's node properties"), implode(null, $html_network_node_properties));
1796
1797        /*
1798         * Network's user verification
1799         */
1800        $html_network_user_verification = array();
1801
1802        //  validation_grace_time
1803        $title = _("Validation grace period");
1804        $help = _("The length of the validation grace period in seconds.  A new user is granted Internet access for this period check his email and validate his account.");
1805        $data = InterfaceElements::generateInputText("network_" . $this->getId() . "_validation_grace_time", $this->getValidationGraceTime(), "network_validation_grace_time_input");
1806        $html_network_user_verification[] = InterfaceElements::generateAdminSectionContainer("network_validation_grace_time", $title, $data, $help);
1807
1808        //  validation_email_from_address
1809        $title = _("This will be the from address of the validation email");
1810        $data = InterfaceElements::generateInputText("network_" . $this->getId() . "_validation_email_from_address", $this->getValidationEmailFromAddress(), "network_validation_email_from_address_input");
1811        $html_network_user_verification[] = InterfaceElements::generateAdminSectionContainer("network_validation_email_from_address", $title, $data);
1812
1813        //  allow_multiple_login
1814        $title = _("Multiple connections");
1815        $help = _("Can an account be connected more than once at the same time?");
1816        $data = InterfaceElements::generateInputCheckbox("network_" . $this->getId() . "_allow_multiple_login", "", _("Yes"), $this->getMultipleLoginAllowed(), "network_allow_multiple_login_radio");
1817        $html_network_user_verification[] = InterfaceElements::generateAdminSectionContainer("network_allow_multiple_login", $title, $data, $help);
1818       
1819         
1820        //  network_authenticator_params
1821        $title = _("Case sensitivity");
1822        $help = _("Are usernames case sensitive?");
1823        $data = InterfaceElements::generateInputCheckbox("network_" . $this->getId() . "_usernames_case_sensitive","", _("Yes"), $this->getUsernamesCaseSensitive(), "network_usernames_case_sensitive");
1824        $html_network_user_verification[] = InterfaceElements::generateAdminSectionContainer("network_usernames_case_sensitive", $title, $data, $help);
1825
1826        // Build section
1827        $html .= InterfaceElements::generateAdminSectionContainer("network_user_verification", _("Network's user verification"), implode(null, $html_network_user_verification));
1828
1829        /*
1830         * Dynamic abuse control
1831         */
1832        $html_dynamic_abuse_control = array();
1833        $permArray=null;
1834        $permArray[]=array(Permission::P('NETWORK_PERM_EDIT_DYNAMIC_ABUSE_CONTROL'), $this);
1835        if (Security::hasAnyPermission($permArray)) {
1836            //  connection_limit_window
1837            $title = _("Abuse control window");
1838            $help = _("The length of the window during which the user must not have exceeded the limits below.  Any valid postgresql interval expression is acceptable, typically '1 month' '1 week'.  A user who exceeds the limits will be denied access until his usage falls below the limits.");
1839            $data = InterfaceElements::generateInputText("network_" . $this->getId() . "_connection_limit_window", $this->getConnectionLimitWindow(), "network_connection_limit_window_input");
1840            $html_dynamic_abuse_control[] = InterfaceElements::generateAdminSectionContainer("network_connection_limit_window", $title, $data, $help);
1841
1842            //  connection_limit_network_max_total_bytes
1843            $title = _("Network max total bytes transfered");
1844            $help = _("Maximum data transfer during the abuse control window");
1845            $data = InterfaceElements::generateInputText("network_" . $this->getId() . "_connection_limit_network_max_total_bytes", $this->getConnectionLimitNetworkMaxTotalBytes(), "network_connection_limit_network_max_total_bytes");
1846            $html_dynamic_abuse_control[] = InterfaceElements::generateAdminSectionContainer("network_connection_limit_network_max_total_bytes", $title, $data, $help);
1847
1848            //  connection_limit_network_max_usage_duration
1849            $title = _("Network max connection duration");
1850            $help = _("Maximum connection duration during the abuse control window.  Any valid postgresql interval expression is acceptable, such as hh:mm:ss");
1851            $data = InterfaceElements::generateInputText("network_" . $this->getId() . "_connection_limit_network_max_usage_duration", $this->getConnectionLimitNetworkMaxDuration(), "network_connection_limit_network_max_usage_duration");
1852            $html_dynamic_abuse_control[] = InterfaceElements::generateAdminSectionContainer("network_connection_limit_network_max_usage_duration", $title, $data, $help);
1853
1854            //  connection_limit_node_max_total_bytes
1855            $title = _("Node max total bytes transfered");
1856            $help = _("Maximum data transfer during the abuse control window");
1857            $data = InterfaceElements::generateInputText("network_" . $this->getId() . "_connection_limit_node_max_total_bytes", $this->getConnectionLimitNodeMaxTotalBytes(), "network_connection_limit_node_max_total_bytes");
1858            $html_dynamic_abuse_control[] = InterfaceElements::generateAdminSectionContainer("network_connection_limit_node_max_total_bytes", $title, $data, $help);
1859
1860            //  connection_limit_node_max_usage_duration
1861            $title = _("Node max connection duration");
1862            $help = _("Maximum connection duration during the abuse control window.  Any valid postgresql interval expression is acceptable, such as hh:mm:ss");
1863            $data = InterfaceElements::generateInputText("network_" . $this->getId() . "_connection_limit_node_max_usage_duration", $this->getConnectionLimitNodeMaxDuration(), "network_connection_limit_node_max_usage_duration");
1864            $html_dynamic_abuse_control[] = InterfaceElements::generateAdminSectionContainer("network_connection_limit_node_max_usage_duration", $title, $data, $help);
1865        }
1866        else{
1867            $html_dynamic_abuse_control[] = _("You do not have access to edit these options");
1868        }
1869        // Build section
1870        $html .= InterfaceElements::generateAdminSectionContainer("network_user_verification", _("Dynamic abuse control"), implode(null, $html_dynamic_abuse_control));
1871
1872        /*
1873         * Access management
1874         */
1875        $html_access_rights = array();
1876
1877        /*
1878         * Access rights
1879         */
1880        if (true) {
1881            require_once('classes/Stakeholder.php');
1882            $html_access_rights = Stakeholder::getAssignStakeholdersUI($this);
1883            $html .= InterfaceElements::generateAdminSectionContainer("access_rights", _("Access rights"), $html_access_rights);
1884        }
1885        /*
1886         * Network GIS data
1887         */
1888        if (defined('GMAPS_HOTSPOTS_MAP_ENABLED') && GMAPS_HOTSPOTS_MAP_ENABLED == true) {
1889            $html_network_gis_data = array();
1890
1891            $gis_point = $this->getGisLocation();
1892            $gis_lat_name = "network_" . $this->getId() . "_gis_latitude";
1893            $gis_lat_value = htmlspecialchars($gis_point->getLatitude(), ENT_QUOTES);
1894            $gis_long_name = "network_" . $this->getId() . "_gis_longitude";
1895            $gis_long_value = htmlspecialchars($gis_point->getLongitude(), ENT_QUOTES);
1896            $gis_alt_name = "network_" . $this->getId() . "_gis_altitude";
1897            $gis_alt_value = htmlspecialchars($gis_point->getAltitude(), ENT_QUOTES);
1898
1899            $html_network_gis_data[] = '<p>'._("Note that to be valid, all 3 values must be present.")."</p>\n";
1900            $title = _("Latitude");
1901            $help = _("Center latitude for the area covered by your wireless network");
1902            $data = InterfaceElements::generateInputText($gis_lat_name, $gis_lat_value, "network_gis_latitude_input");
1903            $html_network_gis_data[] = InterfaceElements::generateAdminSectionContainer("network_gis_latitude", $title, $data, $help);
1904
1905            $title = _("Longitude");
1906            $help = _("Center longitude for the area covered by your wireless network");
1907            $data = InterfaceElements::generateInputText($gis_long_name, $gis_long_value, "network_gis_longitude_input");
1908            $html_network_gis_data[] = InterfaceElements::generateAdminSectionContainer("network_gis_longitude", $title, $data, $help);
1909
1910            $title = _("Zoomlevel");
1911            $help = _("Zoomlevel of the Google Map.  12 is a typical value.");
1912            $data = InterfaceElements::generateInputText($gis_alt_name, $gis_alt_value, "network_gis_altitude_input");
1913            $html_network_gis_data[] = InterfaceElements::generateAdminSectionContainer("network_gis_altitude", $title, $data, $help);
1914
1915            $title = _("Map type");
1916            $help = _("Default Google Map type for your the area of your wireless network");
1917            $data = $this->getSelectGisMapType("network_" . $this->getId() . "_gmaps_map_type", $this->getGisMapType());
1918            $html_network_gis_data[] = InterfaceElements::generateAdminSectionContainer("network_gmaps_map_type", $title, $data, $help);
1919
1920            // Build section
1921            $html .= InterfaceElements::generateAdminSectionContainer("network_gis_data", _("GIS data"), implode(null, $html_network_gis_data));
1922        }
1923
1924        // Profile templates
1925        $title = _("Network profile templates");
1926        $name = "network_".$this->_id."_profile_templates";
1927        $data = ProfileTemplate::getLinkedProfileTemplateUI($name, "network_has_profile_templates", "network_id", $this->_id);
1928        $html .= InterfaceElements::generateAdminSectionContainer("network_profile_templates", $title, $data);
1929       
1930        // objects hierarchy
1931        $html .= parent::getGraphAdminUI($this);
1932
1933        $html .= "</ul>\n";
1934        $html .= "</fieldset>";
1935
1936        return $html;
1937    }
1938
1939    /**
1940     * Process admin interface of this object.
1941     *
1942     * @return void
1943     *
1944     * @access public
1945     */
1946    public function processAdminUI()
1947    {
1948        Security::requirePermission(Permission::P('NETWORK_PERM_EDIT_NETWORK_CONFIG'), $this);
1949
1950        // Content management
1951        parent::processContentAdminUI();
1952        /* $name = "network_".$this->_id."_content";
1953        Content :: processLinkedContentUI($name, 'network_has_content', 'network_id', $this->_id);*/
1954
1955        // name
1956        $name = "network_".$this->getId()."_name";
1957        $this->setName($_REQUEST[$name]);
1958
1959        // creation_date
1960        $name = "network_".$this->getId()."_creation_date";
1961        $this->setCreationDate($_REQUEST[$name]);
1962
1963        // homepage_url
1964        $name = "network_".$this->getId()."_homepage_url";
1965        $this->setWebSiteUrl($_REQUEST[$name]);
1966
1967        // tech_support_email
1968        $name = "network_".$this->getId()."_tech_support_email";
1969        $this->setTechSupportEmail($_REQUEST[$name]);
1970
1971        //  network_authenticator_class
1972        $name = "network_".$this->getId()."_network_authenticator_class";
1973        $this->setAuthenticatorClassName($_REQUEST[$name]);
1974
1975        //  network_authenticator_params
1976        $name = "network_".$this->getId()."_network_authenticator_params";
1977        $this->setAuthenticatorConstructorParams($_REQUEST[$name]);
1978
1979        //  is_default_network
1980        $name = "network_".$this->getId()."_is_default_network";
1981        if (!empty ($_REQUEST[$name]) && $_REQUEST[$name] == 'on')
1982        $this->setAsDefaultNetwork();
1983
1984        //  validation_grace_time
1985        $name = "network_".$this->getId()."_validation_grace_time";
1986        $this->setValidationGraceTime($_REQUEST[$name]);
1987
1988        //  validation_email_from_address
1989        $name = "network_".$this->getId()."_validation_email_from_address";
1990        $this->setValidationEmailFromAddress($_REQUEST[$name]);
1991       
1992        $name = "network_" . $this->getId() . "_usernames_case_sensitive";
1993        $this->setUsernamesCaseSensitive(empty ($_REQUEST[$name]) ? false : true);
1994
1995        //  theme_pack
1996        $name = "network_".$this->getId()."_theme_pack";
1997        if (!empty ($_REQUEST[$name])) {
1998            $theme_pack = ThemePack::getObject($_REQUEST[$name]);
1999        }
2000        else {
2001            $theme_pack = null;
2002        }
2003        $this->setThemePack($theme_pack);
2004
2005        //  allow_multiple_login
2006        $name = "network_".$this->getId()."_allow_multiple_login";
2007        $this->setMultipleLoginAllowed(empty ($_REQUEST[$name]) ? false : true);
2008
2009        //  allow_splash_only_nodes
2010        $name = "network_".$this->getId()."_allow_splash_only_nodes";
2011        $this->setSplashOnlyNodesAllowed(empty ($_REQUEST[$name]) ? false : true);
2012
2013        //  allow_custom_portal_redirect
2014        $name = "network_".$this->getId()."_allow_custom_portal_redirect";
2015        $this->setCustomPortalRedirectAllowed(empty ($_REQUEST[$name]) ? false : true);
2016
2017        //  'allow_original_URL_redirect
2018        $name = "network_".$this->getId()."_allow_original_URL_redirect";
2019        $this->setPortalOriginalUrlAllowed(empty ($_REQUEST[$name]) ? false : true);
2020
2021        /*
2022         * Dynamic abuse control
2023         */
2024        $html_dynamic_abuse_control = array();
2025        $permArray=null;
2026        $permArray[]=array(Permission::P('NETWORK_PERM_EDIT_DYNAMIC_ABUSE_CONTROL'), $this);
2027        if (Security::hasAnyPermission($permArray)) {
2028            //  connection_limit_window
2029            $name = "network_" . $this->getId() . "_connection_limit_window";
2030            $this->setConnectionLimitWindow($_REQUEST[$name]);
2031
2032            //  connection_limit_network_max_total_bytes
2033            $name = "network_" . $this->getId() . "_connection_limit_network_max_total_bytes";
2034            $this->setConnectionLimitNetworkMaxTotalBytes($_REQUEST[$name]);
2035
2036            //  connection_limit_network_max_usage_duration
2037            $name = "network_" . $this->getId() . "_connection_limit_network_max_usage_duration";
2038            $this->setConnectionLimitNetworkMaxDuration($_REQUEST[$name]);
2039
2040            //  connection_limit_node_max_total_bytes
2041            $name = "network_" . $this->getId() . "_connection_limit_node_max_total_bytes";
2042            $this->setConnectionLimitNodeMaxTotalBytes($_REQUEST[$name]);
2043
2044            //  connection_limit_node_max_usage_duration
2045            $name = "network_" . $this->getId() . "_connection_limit_node_max_usage_duration";
2046            $this->setConnectionLimitNodeMaxDuration($_REQUEST[$name]);
2047        }
2048         
2049        // Access rights
2050        require_once('classes/Stakeholder.php');
2051        Stakeholder::processAssignStakeholdersUI($this, $errMsg);
2052        if(!empty($errMsg)) {
2053            echo $errMsg;
2054        }
2055
2056        // GIS data
2057        if (defined('GMAPS_HOTSPOTS_MAP_ENABLED') && GMAPS_HOTSPOTS_MAP_ENABLED == true) {
2058            $gis_lat_name = "network_".$this->getId()."_gis_latitude";
2059            $gis_long_name = "network_".$this->getId()."_gis_longitude";
2060            $gis_alt_name = "network_".$this->getId()."_gis_altitude";
2061            $this->setGisLocation(new GisPoint($_REQUEST[$gis_lat_name], $_REQUEST[$gis_long_name], $_REQUEST[$gis_alt_name]));
2062
2063            $name = "network_".$this->getId()."_gmaps_map_type";
2064            $this->setGisMapType($_REQUEST[$name]);
2065        }
2066
2067        // Profile templates
2068        $name = "network_".$this->_id."_profile_templates";
2069        ProfileTemplate :: processLinkedProfileTemplateUI($name, 'network_has_profile_templates', 'network_id', $this->_id);
2070       
2071        parent::processGraphAdminUI($errMsg, $this);
2072        if(!empty($errMsg)) {
2073            echo $errMsg;
2074            $errMsg = null;
2075        }
2076
2077        // Node creation
2078        $new_node = Node :: processCreateNewObjectUI();
2079        if ($new_node) {
2080            $url = GENERIC_OBJECT_ADMIN_ABS_HREF."?".http_build_query(array ("object_class" => "Node", "action" => "edit", "object_id" => $new_node->getId()));
2081            header("Location: {$url}");
2082        }
2083    }
2084
2085    /**
2086     * Add network-wide content to this network
2087     *
2088     * @param object Content object
2089     *
2090     * @return void
2091     *
2092     * @access public
2093     */
2094 /*   public function addContent(Content $content)
2095    {
2096        $db = AbstractDb::getObject();
2097
2098        $content_id = $db->escapeString($content->getId());
2099        $sql = "INSERT INTO network_has_content (network_id, content_id) VALUES ('$this->_id','$content_id')";
2100        $db->execSqlUpdate($sql, false);
2101    }*/
2102
2103    /**
2104     * Remove network-wide content from this network
2105     *
2106     * @param object Content object
2107     *
2108     * @return void
2109     *
2110     * @access public
2111     */
2112 /*   public function removeContent(Content $content)
2113    {
2114        $db = AbstractDb::getObject();
2115
2116        $content_id = $db->escapeString($content->getId());
2117        $sql = "DELETE FROM network_has_content WHERE network_id='$this->_id' AND content_id='$content_id'";
2118        $db->execSqlUpdate($sql, false);
2119    }*/
2120
2121
2122    /**
2123     * Add a profile template to this network
2124     *
2125     * @param object ProfileTemplate object
2126     *
2127     * @return void
2128     *
2129     * @access public
2130     */
2131    public function addProfileTemplate(ProfileTemplate $profile_template)
2132    {
2133        $db = AbstractDb::getObject();
2134
2135        $profile_template_id = $db->escapeString($profile_template->getId());
2136        $sql = "INSERT INTO network_has_profile_templates (network_id, profile_template_id) VALUES ('$this->_id','$profile_template_id')";
2137        $db->execSqlUpdate($sql, false);
2138    }
2139
2140    /**
2141     * Remove a profile template to this network
2142     *
2143     * @param object ProfileTemplate object
2144     *
2145     * @return void
2146     *
2147     * @access public
2148     */
2149    public function removeProfileTemplate(ProfileTemplate $profile_template)
2150    {
2151        $db = AbstractDb::getObject();
2152
2153        $profile_template_id = $db->escapeString($profile_template->getId());
2154        $sql = "DELETE FROM network_has_profile_templates WHERE network_id='$this->_id' AND profile_template_id='$profile_template_id'";
2155        $db->execSqlUpdate($sql, false);
2156    }
2157
2158    /**Get an array of all ProfileTemplates linked to this network
2159     * @return an array of ProfileTemplates or an empty arrray */
2160    function getAllProfileTemplates() {
2161        $db = AbstractDb::getObject();
2162        $retval = array ();
2163        $profile_template_rows = null;
2164        $sql = "SELECT profile_template_id FROM network_has_profile_templates WHERE network_id='$this->_id'";
2165        $db->execSql($sql, $profile_template_rows, false);
2166        if ($profile_template_rows != null) {
2167            foreach ($profile_template_rows as $profile_template_row) {
2168                $retval[] = ProfileTemplate :: getObject($profile_template_row['profile_template_id']);
2169            }
2170        }
2171        return $retval;
2172    }
2173
2174    /**
2175     * Delete this Object form the it's storage mechanism
2176     *
2177     * @param string &$errmsg Returns an explanation of the error on failure
2178     *
2179     * @return bool true on success, false on failure or access denied
2180     *
2181     * @access public
2182     */
2183    public function delete(& $errmsg)
2184    {
2185        // Init values
2186        $retval = false;
2187        Security::requirePermission(Permission::P('NETWORK_PERM_DELETE_NETWORK'), $this);
2188        if ($this->isDefaultNetwork() === true) {
2189            $errmsg = _('Cannot delete default network, create another one and select it before you remove this one.');
2190        } else {
2191            $db = AbstractDb::getObject();
2192            $id = $db->escapeString($this->getId());
2193            if (!$db->execSqlUpdate("DELETE FROM networks WHERE network_id='{$id}'", false)) {
2194                $errmsg = _('Could not delete network!');
2195            } else {
2196                parent::_delete($errmsg);
2197                $retval = true;
2198            }
2199        }
2200
2201
2202        return $retval;
2203    }
2204    /**
2205     * Reloads the object from the database.
2206     *
2207     * Should normally be called after a set operation
2208     *
2209     * @return void
2210     *
2211     * @access protected
2212     */
2213    protected function refresh()
2214    {
2215        $this->__construct($this->_id);
2216    }
2217
2218    /** Menu hook function */
2219    static public function hookMenu() {
2220        $items = array();
2221        if($networks = Security::getObjectsWithPermission(Permission::P('NETWORK_PERM_EDIT_NETWORK_CONFIG'))) {
2222            foreach ($networks as $networkId => $network) {
2223                $items[] = array('path' => 'network/network_'.$networkId.'edit',
2224                'title' => sprintf(_("Edit %s"), $network->getName()),
2225                'url' => BASE_URL_PATH.htmlspecialchars("admin/generic_object_admin.php?object_class=Network&action=edit&object_id=$networkId")
2226                );
2227            }
2228        }
2229        if(Security::hasPermission(Permission::P('SERVER_PERM_ADD_NEW_NETWORK'), Server::getServer())){
2230            $items[] = array('path' => 'network/network_add_new',
2231                'title' => sprintf(_("Add a new network on this server")),
2232                'url' => BASE_URL_PATH.htmlspecialchars("admin/generic_object_admin.php?object_class=Network&action=new_ui")
2233            );
2234        }
2235        $items[] = array('path' => 'network',
2236                'title' => _('Network administration'),
2237                'type' => MENU_ITEM_GROUPING);
2238        return $items;
2239    }
2240
2241    /**
2242     * Assigns values about network to be processed by the Smarty engine.
2243     *
2244     * @param object $smarty Smarty object
2245     * @param object $net    Network object
2246     *
2247     * @return void
2248     */
2249    public static function assignSmartyValues($smarty, $net = null)
2250    {
2251        if (!$net) {
2252            $net = Network::getCurrentNetwork();
2253        }
2254
2255        // Set network details
2256        $smarty->assign('networkName', $net ? $net->getName() : '');
2257        $smarty->assign('networkWebSiteURL', $net ? $net->getWebSiteURL() : '');
2258        // Set networks usage information
2259        $smarty->assign('networkNumOnlineUsers', $net ? $net->getNumOnlineUsers() : 0);
2260
2261        // Set networks node information
2262        $smarty->assign('networkNumDeployedNodes', $net ? $net->getNumDeployedNodes() : 0);
2263        $smarty->assign('networkNumOnlineNodes', $net ? $net->getNumOnlineNodes() : 0);
2264        $smarty->assign('networkNumNonMonitoredNodes', $net ? $net->getNumOnlineNodes(true) : 0);
2265    }
2266   
2267/**
2268     * Get the type of graph element (read-only for now)
2269     *
2270     * @return string
2271     */
2272    protected function getType() {
2273        return 'Network';
2274    }
2275 
2276    /**
2277     * Return whether this element is a root or has parent (Network is root)
2278     * @return boolean
2279     */
2280    public function isRoot(){
2281        return true;
2282    }
2283   
2284                /**
2285     * Return whether this element is a leaf or has children (Node is leaf)
2286     * @return boolean
2287     */
2288    public function isLeaf() {
2289        return false;
2290    }
2291}
2292
2293/*
2294 * Local variables:
2295 * tab-width: 4
2296 * c-basic-offset: 4
2297 * c-hanging-comment-ender-p: nil
2298 * End:
2299 */
Note: See TracBrowser for help on using the browser.