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

Revision 1428, 81.9 KB (checked in by gbastien, 4 years ago)

* Network can now be set as case insensitive. Emails are now never case sensitive and usernames' case sensitivity is consistent with network settings (#616)
* Yet again some tab alignment

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