*/
require_once BASEPATH.'include/common.php';
require_once 'User.php';
require_once 'GisPoint.php';
require_once 'AbstractGeocoder.php';
require_once 'Utils.php';
/** Abstract a Node. A Node is an actual physical transmitter.
* @todo: Make all the setter functions no-op if the value is the same as what
* was already stored Use setCustomPortalReduirectUrl as an example*/
class Node implements GenericObject
{
private $mRow;
private $mdB; /**< An AbstractDb instance */
private $id;
private static $current_node_id = null;
/** Instantiate a node object
* @param $id The id of the requested node
* @return a Node object, or null if there was an error
*/
static function getObject($id)
{
$object = null;
$object = new self($id);
return $object;
}
/** Get the current node for which the portal is displayed or to which a user is physically connected.
* @param $real_node_only true or false. If true, the real physical node where the user is connected is returned, and the node set by setCurrentNode is ignored.
* @return a Node object, or null if it can't be found.
*/
static function getCurrentNode($real_node_only = false)
{
$object = null;
if (self :: $current_node_id != null && $real_node_only == false)
{
$object = new self(self :: $current_node_id);
}
else
{
$object = self :: getCurrentRealNode();
}
return $object;
}
/** Set the current node where the user is to be considered connected to. (For portal and content display purpuses, among other.
* @param $node Node. The new current node.
* @return true */
static function setCurrentNode(Node $node)
{
self :: $current_node_id = $node->GetId();
return true;
}
/** Get the current node to which a user is physically connected, if any. This is done by an IP adress lookup against the last reported IP adress of the node
* @param * @return a Node object, or null if it can't be found.
*/
public static function getCurrentRealNode()
{
global $db;
$retval = null;
$sql = "SELECT node_id, last_heartbeat_ip from nodes WHERE last_heartbeat_ip='$_SERVER[REMOTE_ADDR]' ORDER BY last_heartbeat_timestamp DESC";
$node_rows = null;
$db->ExecSql($sql, $node_rows, false);
$num_match = count($node_rows);
if ($num_match == 0)
{
// User is not physically connected to a node
$retval = null;
}
else
if ($num_match = 1)
{
// Only a single node matches, the user is presumed to be there
$retval = new self($node_rows[0]['node_id']);
}
else
{
/* We have more than one node matching the IP (the nodes are behind the same NAT).
* We will try to discriminate by finding which node the user last authenticated against.
* If the IP matches, we can be pretty certain the user is there.
*/
$retval = null;
$current_user = User :: getCurrentUser();
if ($current_user != null)
{
$current_user_id = $current_user->getId();
$_SERVER['REMOTE_ADDR'];
$sql = "SELECT node_id, last_heartbeat_ip from connections NATURAL JOIN nodes WHERE user_id='$current_user_id' ORDER BY last_updated DESC ";
$db->ExecSql($sql, $node_rows, false);
$node_row = $node_rows[0];
if ($node_row != null && $node_row['last_heartbeat_ip'] == $_SERVER['REMOTE_ADDR'])
{
$retval = new self($node_row['node_id']);
}
}
}
return $retval;
}
public function delete(& $errmsg)
{
$retval = false;
$user = User :: getCurrentUser();
if ($this->isOwner($user) || $user->isSuperAdmin())
{
global $db;
$id = $db->EscapeString($this->getId());
if (!$db->ExecSqlUpdate("DELETE FROM nodes WHERE node_id='{$id}'", false))
{
$errmsg = _('Could not delete node!');
}
else
{
$retval = true;
}
}
else
{
$errmsg = _('Access denied!');
}
return $retval;
}
/** Create a new Node in the database
* @param $node_id The id to be given to the new node. If not present, a
* guid will be assigned.
* @param $network Network object. The node's network. If not present,
* the current Network will be assigned
*
* @return the newly created Node object, or null if there was an error
*/
static function createNewObject($node_id = null, $network = null)
{
global $db;
if (empty ($node_id))
{
$node_id = get_guid();
}
$node_id = $db->EscapeString($node_id);
if (empty ($network))
{
$network = Network :: getCurrentNetwork();
}
$network_id = $db->EscapeString($network->getId());
$node_deployment_status = $db->EscapeString("IN_PLANNING");
$node_name = _("New node");
if (Node :: nodeExists($node_id))
throw new Exception(_('This node already exists.'));
$sql = "INSERT INTO nodes (node_id, network_id, creation_date, node_deployment_status, name) VALUES ('$node_id', '$network_id', NOW(),'$node_deployment_status', '$node_name')";
if (!$db->ExecSqlUpdate($sql, false))
{
throw new Exception(_('Unable to insert new node into database!'));
}
$object = new self($node_id);
return $object;
}
/** Get an interface to pick a node.
* @param $user_prefix A identifier provided by the programmer to recognise it's generated html form
* @param $sql_additional_where Addidional where conditions to restrict the candidate objects
* @return html markup
*/
public static function getSelectNodeUI($user_prefix, $sql_additional_where = null)
{
global $db;
$html = '';
$name = "{$user_prefix}";
$html .= _("Node: ");
$sql = "SELECT node_id, name from nodes WHERE 1=1 $sql_additional_where ORDER BY node_id";
$node_rows = null;
$db->ExecSql($sql, $node_rows, false);
if ($node_rows != null)
{
$i = 0;
foreach ($node_rows as $node_row)
{
$tab[$i][0] = $node_row['node_id'];
$tab[$i][1] = $node_row['node_id'].": ".$node_row['name'];
$i ++;
}
$html .= FormSelectGenerator :: generateFromArray($tab, null, $name, null, false);
}
return $html;
}
/** Get the selected Network object.
* @param $user_prefix A identifier provided by the programmer to recognise it's generated form
* @return the node object
*/
static function processSelectNodeUI($user_prefix)
{
$object = null;
$name = "{$user_prefix}";
return new self($_REQUEST[$name]);
}
/** Get an interface to create a new node.
* @param $network Optional: The network to which the new node will belong,
* if absent, the user will be prompted.
* @return html markup
*/
public static function getCreateNewObjectUI($network = null)
{
$html = '';
$html .= _("Create new node with id")." \n";
$name = "new_node_id";
$html .= "\n";
if ($network)
{
$name = "new_node_network_id";
$html .= "\n";
}
else
{
$html .= " "._("in network:")." \n";
$html .= Network :: getSelectNetworkUI('new_node');
}
return $html;
}
/** Process the new object interface.
* Will return the new object if the user has the credentials and the form was fully filled.
* @return the node object or null if no new node was created.
*/
static function processCreateNewObjectUI()
{
$retval = null;
$name = "new_node_id";
if (!empty ($_REQUEST[$name]))
{
$node_id = $_REQUEST[$name];
$name = "new_node_network_id";
if (!empty ($_REQUEST[$name]))
{
$network = Network :: getObject($_REQUEST[$name]);
}
else
{
$network = Network :: processSelectNetworkUI('new_node');
}
if ($node_id && $network)
{
if (!$network->hasAdminAccess(User :: getCurrentUser()))
{
throw new Exception(_("Access denied"));
}
$retval = self :: createNewObject($node_id, $network);
}
}
return $retval;
}
/** Get an interface to select the deployment status
* @param $user_prefix A identifier provided by the programmer to recognise it's generated html form
* @return html markup
*/
public function getSelectDeploymentStatus($user_prefix)
{
global $db;
$html = '';
$name = "{$user_prefix}";
$status_list = null;
$db->ExecSql("SELECT node_deployment_status FROM node_deployment_status", $status_list, false);
if ($status_list == null)
throw new Exception(_("No deployment statues could be found in the database"));
$tab = array ();
foreach ($status_list as $status)
$tab[] = array ($status['node_deployment_status'], $status['node_deployment_status']);
$html .= FormSelectGenerator :: generateFromArray($tab, $this->getDeploymentStatus(), $name, null, false);
return $html;
}
/** Get the selected deployment status
* @param $user_prefix A identifier provided by the programmer to recognise it's generated form
* @return the deployment status
*/
public function processSelectDeploymentStatus($user_prefix)
{
$object = null;
$name = "{$user_prefix}";
return $_REQUEST[$name];
}
/** @param $node_id The id of the node */
private function __construct($node_id)
{
global $db;
$this->mDb = & $db;
$node_id_str = $db->EscapeString($node_id);
$sql = "SELECT * FROM nodes WHERE node_id='$node_id_str'";
$row = null;
$db->ExecSqlUniqueRes($sql, $row, false);
if ($row == null)
{
throw new Exception(_("The id $node_id_str could not be found in the database"));
}
$this->mRow = $row;
$this->id = $row['node_id'];
}
function getId()
{
return $this->id;
}
/** Changing the id of a Node is supported.
* Be carefull to anly call this when all other changes are processed,
* or the id used to generate the form names may no longer match.
* @param $id, string, the new node id.
* @return true on success, false on failure. Check this,
* as it's possible that someone will enter an existing id, especially
* if the MAC address is used and hardware is recycled.
*/
function setId($id)
{
$id = $this->mDb->EscapeString($id);
$retval = $this->mDb->ExecSqlUpdate("UPDATE nodes SET node_id = '{$id}' WHERE node_id = '{$this->getId()}'");
if($retval)
{
$this->id = $id;
$this->refresh();
}
return $retval;
}
/** Gets the Network to which the node belongs
* @return Network object (never returns null)
*/
public function getNetwork()
{
return Network :: getObject($this->mRow['network_id']);
}
/** Get a GisPoint object ; altide is not supported yet
*/
function getGisLocation()
{
// Altitude is not supported yet
return new GisPoint($this->mRow['latitude'], $this->mRow['longitude'], 0);
}
function setGisLocation($pt)
{
if (!empty ($pt))
{
$lat = $this->mDb->EscapeString($pt->getLatitude());
$long = $this->mDb->EscapeString($pt->getLongitude());
if (!empty ($lat) && !empty ($long))
$this->mDb->ExecSqlUpdate("UPDATE nodes SET latitude = $lat, longitude = $long WHERE node_id = '{$this->getId()}'");
else
$this->mDb->ExecSqlUpdate("UPDATE nodes SET latitude = NULL, longitude = NULL WHERE node_id = '{$this->getId()}'");
$this->refresh();
}
}
/** Return the name of the node
*/
function getName()
{
return $this->mRow['name'];
}
function setName($name)
{
$name = $this->mDb->EscapeString($name);
$this->mDb->ExecSqlUpdate("UPDATE nodes SET name = '{$name}' WHERE node_id = '{$this->getId()}'");
$this->refresh();
}
function getCreationDate()
{
return $this->mRow['creation_date'];
}
function getHomePageURL()
{
return $this->mRow['home_page_url'];
}
function setHomePageUrl($url)
{
$url = $this->mDb->EscapeString($url);
$this->mDb->ExecSqlUpdate("UPDATE nodes SET home_page_url = '{$url}' WHERE node_id = '{$this->getId()}'");
$this->refresh();
}
function getDescription()
{
return $this->mRow['description'];
}
function setDescription($description)
{
$description = $this->mDb->EscapeString($description);
$this->mDb->ExecSqlUpdate("UPDATE nodes SET description = '{$description}' WHERE node_id = '{$this->getId()}'");
$this->refresh();
}
function getMapURL()
{
return $this->mRow['map_url'];
}
function setMapURL($url)
{
$url = $this->mDb->EscapeString($url);
$this->mDb->ExecSqlUpdate("UPDATE nodes SET map_url = '{$url}' WHERE node_id = '{$this->getId()}'");
$this->refresh();
}
public function getCivicNumber()
{
return $this->mRow['civic_number'];
}
public function setCivicNumber($civic_number)
{
$civic_number = $this->mDb->EscapeString($civic_number);
$this->mDb->ExecSqlUpdate("UPDATE nodes SET civic_number = '{$civic_number}' WHERE node_id = '{$this->getId()}'");
$this->refresh();
}
public function getStreetName()
{
return $this->mRow['street_name'];
}
public function setStreetName($street_name)
{
$street_name = $this->mDb->EscapeString($street_name);
$this->mDb->ExecSqlUpdate("UPDATE nodes SET street_name = '{$street_name}' WHERE node_id = '{$this->getId()}'");
$this->refresh();
}
public function getCity()
{
return $this->mRow['city'];
}
public function setCity($city)
{
$city = $this->mDb->EscapeString($city);
$this->mDb->ExecSqlUpdate("UPDATE nodes SET city = '{$city}' WHERE node_id = '{$this->getId()}'");
$this->refresh();
}
public function getProvince()
{
return $this->mRow['province'];
}
public function setProvince($province)
{
$province = $this->mDb->EscapeString($province);
$this->mDb->ExecSqlUpdate("UPDATE nodes SET province = '{$province}' WHERE node_id = '{$this->getId()}'");
$this->refresh();
}
public function getCountry()
{
return $this->mRow['country'];
}
protected function setCountry($country)
{
$country = $this->mDb->EscapeString($country);
$this->mDb->ExecSqlUpdate("UPDATE nodes SET country = '{$country}' WHERE node_id = '{$this->getId()}'");
$this->refresh();
}
public function getPostalCode()
{
return $this->mRow['postal_code'];
}
public function setPostalCode($postal_code)
{
$postal_code = $this->mDb->EscapeString($postal_code);
$this->mDb->ExecSqlUpdate("UPDATE nodes SET postal_code = '{$postal_code}' WHERE node_id = '{$this->getId()}'");
$this->refresh();
}
function getTelephone()
{
return $this->mRow['public_phone_number'];
}
function setTelephone($phone)
{
$phone = $this->mDb->EscapeString($phone);
$this->mDb->ExecSqlUpdate("UPDATE nodes SET public_phone_number = '{$phone}' WHERE node_id = '{$this->getId()}'");
$this->refresh();
}
function getTransitInfo()
{
return $this->mRow['mass_transit_info'];
}
function setTransitInfo($transit_info)
{
$transit_info = $this->mDb->EscapeString($transit_info);
$this->mDb->ExecSqlUpdate("UPDATE nodes SET mass_transit_info = '{$transit_info}' WHERE node_id = '{$this->getId()}'");
$this->refresh();
}
function getEmail()
{
return $this->mRow['public_email'];
}
function setEmail($email)
{
$email = $this->mDb->EscapeString($email);
$this->mDb->ExecSqlUpdate("UPDATE nodes SET public_email = '{$email}' WHERE node_id = '{$this->getId()}'");
$this->refresh();
}
function getDeploymentStatus()
{
return $this->mRow['node_deployment_status'];
}
function setDeploymentStatus($status)
{
$status = $this->mDb->EscapeString($status);
$this->mDb->ExecSqlUpdate("UPDATE nodes SET node_deployment_status = '{$status}' WHERE node_id = '{$this->getId()}'");
$this->refresh();
}
function getLastPaged()
{
return $this->mRow['last_paged'];
}
function setLastPaged($last_paged)
{
$this->mDb->ExecSqlUpdate("UPDATE nodes SET last_paged = {$last_paged}::abstime WHERE node_id = '{$this->getId()}'");
$this->refresh();
}
function getLastHeartbeatIP()
{
return $this->mRow['last_heartbeat_ip'];
}
function getLastHeartbeatUserAgent()
{
return $this->mRow['last_heartbeat_user_agent'];
}
function getLastHeartbeatTimestamp()
{
return $this->mRow['last_heartbeat_timestamp'];
}
function setLastHeartbeatTimestamp($timestamp)
{
$this->mDb->ExecSqlUpdate("UPDATE nodes SET last_heartbeat_timestamp = '{$timestamp}' WHERE node_id = '{$this->getId()}'");
$this->refresh();
}
/** Is the node a Splash Only node? Will only return true if the Network configuration allows it.
* @return true or false */
public function isSplashOnly()
{
return $this->getNetwork()->getSplashOnlyNodesAllowed() && $this->isConfiguredSplashOnly();
}
/** Is the node configured as a Splash Only node? This is NOT the same as isSplashOnly().
* This is the getter for the configuration set in the database for this node.
* For the node to actually be splash only, this AND the network
* gonfiguration must match.
* @return true or false */
public function isConfiguredSplashOnly()
{
return (($this->mRow['is_splash_only_node'] == 't') ? true : false);
}
/** Set if this node should be a splash-only (no login) node (if enabled in Network configuration)
* @param $value The new value, true or false
* @return true on success, false on failure */
function setIsConfiguredSplashOnly($value)
{
$retval = true;
if ($value != $this->isConfiguredSplashOnly())
{
global $db;
$value ? $value = 'TRUE' : $value = 'FALSE';
$retval = $db->ExecSqlUpdate("UPDATE nodes SET is_splash_only_node = {$value} WHERE node_id = '{$this->getId()}'", false);
$this->refresh();
}
return $retval;
}
/** The url to show instead of the portal. If empty, the portal is shown
Must be enabled in the Network configuration to have any effect
@return a string */
function getCustomPortalRedirectUrl()
{
return $this->mRow['custom_portal_redirect_url'];
}
/** The url to show instead of the portal. If empty, the portal is shown
Must be enabled in the Network configuration to have any effect
@return true on success, false on failure */
function setCustomPortalRedirectUrl($value)
{
$retval = true;
if ($value != $this->getCustomPortalRedirectUrl())
{
global $db;
$value = $db->EscapeString($value);
$retval = $db->ExecSqlUpdate("UPDATE nodes SET custom_portal_redirect_url = '{$value}' WHERE node_id = '{$this->getId()}'", false);
$this->refresh();
}
return $retval;
}
/** Retrieves the admin interface of this object.
* @return The HTML fragment for this interface */
public function getAdminUI()
{
//TODO: Most of this code will be moved to Hotspot class when the abtraction will be completed
//pretty_print_r($_REQUEST);
//pretty_print_r($this->mRow);
$html = '';
$html .= "
\n";
// Hashed node_id (this is a workaround since PHP auto-converts HTTP vars var periods, spaces or underscores )
$hashed_node_id = md5($this->getId());
// Node ID
$value = htmlspecialchars($this->getId(), ENT_QUOTES);
$html .= "
\n";
/*
* If Google Maps is enabled, call the geocoding service,
* then use Google Maps to let the user choose a more precise location
*
* otherwise
*
* Simply use a geocoding service.
*/
if (defined('GMAPS_HOTSPOTS_MAP_ENABLED') && GMAPS_HOTSPOTS_MAP_ENABLED === true)
{
$html .= "
\n";
$html .= "
\n";
$html .= "\n";
$html .= "\n";
$html .= " ("._("Use a geocoding service, then use Google Maps to pinpoint the exact location.").")";
$html .= "
\n";
return $html;
}
/** Process admin interface of this object.
*/
public function processAdminUI()
{
$user = User :: getCurrentUser();
if (!$this->isOwner($user) && !$user->isSuperAdmin())
{
throw new Exception(_('Access denied!'));
}
// Information about the node
// Hashed node_id (this is a workaround since PHP auto-converts HTTP vars var periods, spaces or underscores )
$hashed_node_id = md5($this->getId());
// Name
$name = "node_".$hashed_node_id."_name";
$this->setName($_REQUEST[$name]);
// Homepage URL
$name = "node_".$hashed_node_id."_homepage_url";
$this->setHomePageUrl($_REQUEST[$name]);
// Description
$name = "node_".$hashed_node_id."_description";
$this->setDescription($_REQUEST[$name]);
// Map URL
$name = "node_".$hashed_node_id."_map_url";
$this->setMapUrl($_REQUEST[$name]);
// Civic number
$name = "node_".$hashed_node_id."_civic_number";
$this->setCivicNumber($_REQUEST[$name]);
// Street name
$name = "node_".$hashed_node_id."_street_name";
$this->setStreetName($_REQUEST[$name]);
// City
$name = "node_".$hashed_node_id."_city";
$this->setCity($_REQUEST[$name]);
// Province
$name = "node_".$hashed_node_id."_province";
$this->setProvince($_REQUEST[$name]);
// Postal Code
$name = "node_".$hashed_node_id."_postal_code";
$this->setPostalCode($_REQUEST[$name]);
// Country
$name = "node_".$hashed_node_id."_country";
$this->setCountry($_REQUEST[$name]);
// Public phone #
$name = "node_".$hashed_node_id."_public_phone";
$this->setTelephone($_REQUEST[$name]);
// Public mail
$name = "node_".$hashed_node_id."_public_email";
$this->setEmail($_REQUEST[$name]);
// Mass transit info
$name = "node_".$hashed_node_id."_mass_transit_info";
$this->setTransitInfo($_REQUEST[$name]);
// GIS data
// Get a geocoder for a given country
if (!empty ($_REQUEST['geocode_only']))
{
$geocoder = AbstractGeocoder :: getGeocoder($this->getCountry());
if ($geocoder != null)
{
$geocoder->setCivicNumber($this->getCivicNumber());
$geocoder->setStreetName($this->getStreetName());
$geocoder->setCity($this->getCity());
$geocoder->setProvince($this->getProvince());
$geocoder->setPostalCode($this->getPostalCode());
if ($geocoder->validateAddress() === true)
{
if (($point = $geocoder->getGisLocation()) !== null)
$this->setGisLocation($point);
else
echo _("It appears that the Geocoder could not be reached or could not geocode the given address.");
}
else
echo _("You must enter a valid address.");
}
}
else
{
// Use what has been set by the user.
$gis_lat_name = "node_".$hashed_node_id."_gis_latitude";
$gis_long_name = "node_".$hashed_node_id."_gis_longitude";
$this->setGisLocation(new GisPoint($_REQUEST[$gis_lat_name], $_REQUEST[$gis_long_name], .0));
}
// Statistics
$name = "node_{$this->id}_get_stats";
if (!empty ($_REQUEST[$name]))
header("Location: stats.php?node_id=".urlencode($this->getId()));
// Node configuration section
$network = $this->getNetwork();
// Deployment status
$name = "node_".$hashed_node_id."_deployment_status";
$this->setDeploymentStatus(self :: processSelectDeploymentStatus($name));
// is_splash_only_node
if ($network->getSplashOnlyNodesAllowed())
{
$name = "node_".$hashed_node_id."_is_splash_only_node";
$this->setIsConfiguredSplashOnly(empty ($_REQUEST[$name]) ? false : true);
}
// custom_portal_redirect_url
if ($network->getCustomPortalRedirectAllowed())
{
$name = "node_".$hashed_node_id."_custom_portal_redirect_url";
$this->setCustomPortalRedirectUrl($_REQUEST[$name]);
}
// End Node configuration section
// Owners processing
// Rebuild user id, and delete if it was selected
foreach ($this->getOwners() as $owner)
{
$name = "node_{$this->getId()}_owner_{$owner->GetId()}_remove";
if (!empty ($_REQUEST[$name]))
{
if ($this->isOwner($owner))
$this->removeOwner($owner);
else
echo _("Invalid user!");
}
}
$name = "node_{$this->getId()}_new_owner_submit";
if (!empty ($_REQUEST[$name]))
{
$name = "node_{$this->getId()}_new_owner";
$owner = User :: processSelectUserUI($name);
if ($owner)
{
if ($this->isOwner($owner))
echo _("The user is already an owner of this node.");
else
$this->addOwner($owner);
}
}
// Technical officers processing
// Rebuild user id, and delete if it was selected
foreach ($this->getTechnicalOfficers() as $tech_officer)
{
$name = "node_{$this->getId()}_tech_officer_{$tech_officer->GetId()}_remove";
if (!empty ($_REQUEST[$name]))
{
if ($this->isTechnicalOfficer($tech_officer))
$this->removeTechnicalOfficer($tech_officer);
else
echo _("Invalid user!");
}
}
$name = "node_{$this->getId()}_new_tech_officer_submit";
if (!empty ($_REQUEST[$name]))
{
$name = "node_{$this->getId()}_new_tech_officer";
$tech_officer = User :: processSelectUserUI($name);
if ($tech_officer)
{
if ($this->isTechnicalOfficer($tech_officer))
echo _("The user is already a technical officer of this node.");
else
$this->addTechnicalOfficer($tech_officer);
}
}
// Content processing
$name = "node_{$this->id}_content_login";
Content::processLinkedContentUI($name, 'node_has_content', 'node_id', $this->id);
$name = "node_{$this->id}_content_portal";
Content::processLinkedContentUI($name, 'node_has_content', 'node_id', $this->id);
// Name
$name = "node_".$hashed_node_id."_id";
$this->setId($_REQUEST[$name]);
}
// Redirect to this node's portal page
public function getUserUI()
{
header("Location: ".BASE_SSL_PATH."portal/?gw_id=".$this->getId());
}
/** Add content to this node */
public function addContent(Content $content)
{
global $db;
$content_id = $db->EscapeString($content->getId());
$sql = "INSERT INTO node_has_content (node_id, content_id) VALUES ('$this->id','$content_id')";
$db->ExecSqlUpdate($sql, false);
}
/** Remove content from this node */
public function removeContent(Content $content)
{
global $db;
$content_id = $db->EscapeString($content->getId());
$sql = "DELETE FROM node_has_content WHERE node_id='$this->id' AND content_id='$content_id'";
$db->ExecSqlUpdate($sql, false);
}
/**Get an array of all Content linked to this node
* @param boolean $exclude_subscribed_content
* @param User $subscriber The User object used to discriminate the content
* @param $display_location Only select the content to be displayed in thios
* area. Defaults to 'portal_page'
* @return an array of Content or an empty arrray */
function getAllContent($exclude_subscribed_content = false, $subscriber = null, $display_location='portal_page')
{
global $db;
$retval = array ();
$content_rows = null;
// Get all network, but exclude user subscribed content if asked
if ($exclude_subscribed_content == true && $subscriber)
$sql = "SELECT content_id FROM node_has_content WHERE node_id='{$this->id}' AND display_location='$display_location' AND content_id NOT IN (SELECT content_id FROM user_has_content WHERE user_id = '{$subscriber->getId()}') ORDER BY subscribe_timestamp DESC";
else
$sql = "SELECT content_id FROM node_has_content WHERE node_id='{$this->id}' AND display_location='$display_location' ORDER BY subscribe_timestamp DESC";
$db->ExecSql($sql, $content_rows, false);
if ($content_rows != null)
{
foreach ($content_rows as $content_row)
{
$retval[] = Content :: getObject($content_row['content_id']);
}
}
return $retval;
}
/** Get an array of all artistic and locative Content for this hotspot
* @return an array of Content or an empty arrray */
function getAllLocativeArtisticContent()
{
global $db;
$retval = array ();
$sql = "SELECT * FROM content_group JOIN content ON (content.content_id = content_group.content_group_id) JOIN node_has_content ON (node_has_content.content_id = content_group.content_group_id AND node_has_content.node_id = '{$this->getId()}') WHERE is_persistent = true AND is_artistic_content = true AND is_locative_content = true ORDER BY subscribe_timestamp DESC";
$content_rows = null;
$db->ExecSql($sql, $content_rows, false);
if ($content_rows != null)
{
foreach ($content_rows as $content_row)
{
// Create a content group object and grab only those that have content for the current Node
$content_group = Content :: getObject($content_row['content_group_id']);
if ($content_group->getDisplayNumElements() >= 1)
{
if ($content_group->isDisplayableAt($this))
{
// Disable logging and allow content to expand ( if possible )
$content_group->setExpandStatus(true);
$content_group->setLoggingStatus(false);
$retval[] = $content_group;
}
}
}
}
return $retval;
}
/** The list of users online at this node
* @return An array of User object, or en empty array */
function getOnlineUsers()
{
global $db;
$retval = array ();
$users = null;
$db->ExecSql("SELECT users.user_id FROM users,connections WHERE connections.token_status='".TOKEN_INUSE."' AND users.user_id=connections.user_id AND connections.node_id='{$this->id}'", $users, false);
if ($users != null)
{
foreach ($users as $user_row)
{
$retval[] = User :: getObject($user_row['user_id']);
}
}
return $retval;
}
/** Find out how many users are online this specific Node
* @return Number of online users
*/
function getNumOnlineUsers()
{
global $db;
$retval = array ();
$row = null;
$db->ExecSqlUniqueRes("SELECT COUNT(DISTINCT users.user_id) as count FROM users,connections WHERE connections.token_status='".TOKEN_INUSE."' AND users.user_id=connections.user_id AND connections.node_id='{$this->id}'", $row, false);
return $row['count'];
}
/** The list of all real owners of this node
* @return An array of User object, or en empty array */
function getOwners()
{
global $db;
$retval = array ();
$owners = null;
$db->ExecSql("SELECT user_id FROM node_stakeholders WHERE is_owner = true AND node_id='{$this->id}'", $owners, false);
if ($owners != null)
{
foreach ($owners as $owner_row)
{
$retval[] = User :: getObject($owner_row['user_id']);
}
}
return $retval;
}
/** The list of all Technical officers of this node.
* Technical officers are displayed highlited and in the online user's list,
* and are contacted when the Node goes down.
* @return An array of User object, or en empty array */
function getTechnicalOfficers()
{
global $db;
$retval = array ();
$officers = null;
$db->ExecSql("SELECT user_id FROM node_stakeholders WHERE is_tech_officer = true AND node_id='{$this->id}'", $officers, false);
if ($officers != null)
{
foreach ($officers as $officer_row)
{
$retval[] = User :: getObject($officer_row['user_id']);
}
}
return $retval;
}
/** Associates an owner to this node
* @param User
*/
function addOwner(User $user)
{
global $db;
$rows = null;
$db->ExecSql("SELECT * FROM node_stakeholders WHERE node_id = '{$this->getId()}' AND user_id = '{$user->getId()}'", $rows, false);
if (!$rows)
{
if (!$db->ExecSqlUpdate("INSERT INTO node_stakeholders (node_id, user_id, is_owner) VALUES ('{$this->getId()}','{$user->getId()}', true)", false))
throw new Exception(_('Could not add owner'));
}
else
if (!$db->ExecSqlUpdate("UPDATE node_stakeholders SET is_owner = true WHERE node_id = '{$this->getId()}' AND user_id = '{$user->getId()}';", false))
throw new Exception(_('Could not add owner'));
}
/** Associates a technical officer ( tech support ) to this node
* @param User
*/
function addTechnicalOfficer(User $user)
{
global $db;
$rows = null;
$db->ExecSql("SELECT * FROM node_stakeholders WHERE node_id = '{$this->getId()}' AND user_id = '{$user->getId()}'", $rows, false);
if (!$rows)
{
if (!$db->ExecSqlUpdate("INSERT INTO node_stakeholders (node_id, user_id, is_tech_officer) VALUES ('{$this->getId()}','{$user->getId()}', true)", false))
throw new Exception(_('Could not add tech officer'));
}
else
if (!$db->ExecSqlUpdate("UPDATE node_stakeholders SET is_tech_officer = true WHERE node_id = '{$this->getId()}' AND user_id = '{$user->getId()}';", false))
throw new Exception(_('Could not set existing user as tech officer'));
}
/** Remove owner flag for a stakeholder of this node
* @param User
*/
function removeOwner(User $user)
{
global $db;
if (!$db->ExecSqlUpdate("UPDATE node_stakeholders SET is_owner = false WHERE node_id = '{$this->getId()}' AND user_id = '{$user->getId()}';", false))
throw new Exception(_('Could not remove owner'));
}
/** Remove technical officer flag for a stakeholder of this node
* @param User
*/
function removeTechnicalOfficer(User $user)
{
global $db;
if (!$db->ExecSqlUpdate("UPDATE node_stakeholders SET is_tech_officer = false WHERE node_id = '{$this->getId()}' AND user_id = '{$user->getId()}';", false))
throw new Exception(_('Could not remove tech officer'));
}
/** Is the user an owner of the Node?
* @return true our false*/
function isOwner(User $user)
{
global $db;
if ($user != null)
{
$user_id = $user->getId();
$retval = false;
$row = null;
$db->ExecSqlUniqueRes("SELECT * FROM node_stakeholders WHERE is_owner = true AND node_id='{$this->id}' AND user_id='{$user_id}'", $row, false);
if ($row != null)
{
$retval = true;
}
}
return $retval;
}
/** Is the user a technical officer of the Node?
* @return true our false*/
function isTechnicalOfficer(User $user)
{
global $db;
if ($user != null)
{
$user_id = $user->getId();
$retval = false;
$row = null;
$db->ExecSqlUniqueRes("SELECT * FROM node_stakeholders WHERE is_tech_officer = true AND node_id='{$this->id}' AND user_id='{$user_id}'", $row, false);
if ($row != null)
{
$retval = true;
}
}
return $retval;
}
/** Check if an node exists */
private function nodeExists($id)
{
global $db;
$retval = false;
$id_str = $db->EscapeString($id);
$sql = "SELECT * FROM nodes WHERE node_id='{$id_str}'";
$row = null;
$db->ExecSqlUniqueRes($sql, $row, false);
if ($row != null)
{
$retval = true;
}
return $retval;
}
/** Reloads the object from the database. Should normally be called after a set operation */
protected function refresh()
{
$this->__construct($this->id);
}
} // End class
?>