function __construct($message = false, $tag = '', $expire = false) { // This goes first so that parent constructor will raise an error if the current uuid type doesn't match $this->type = LG_LOG; // Give the new object an ID parent::__construct(); if ($message) { // Set the cmd and data $this->ref1 = LigminchaGlobalServer::getCurrent()->id; $this->tag = $tag; $this->data = $message; $this->expire = $expire; // Store the new log entry in the database $this->update(); } }
/** * Check if the passed Joomla user exists as a global user, create if not */ public static function checkUser($jUser) { // Make a new uuid from the server ID and the user's Joomla ID $server = LigminchaGlobalServer::getCurrent(); $id = self::hash($server->id . ':' . $jUser->id); $user = self::newFromId($id); // Try and load the object data now that we know its uuid if (!$user->load()) { // Doesn't exist, make the data structure for our new user object from $jUser $user->ref1 = $server->id; $user->tag = $jUser->id; $user->data = array('realname' => $jUser->name, 'username' => $jUser->username, 'email' => $jUser->email); // Save our new instance to the DB $user->update(); } return $user; }
/** * Get/create current session instance */ public static function getCurrent() { $update = false; if (is_null(self::$current)) { // If there's a current user, get/make a current session if (LigminchaGlobalUser::getCurrent()) { // None found, create new // - there will already be a current session established if one existed thanks to SSO::makeSessionFromCookie self::$current = new LigminchaGlobalSession(); // Doesn't exist, make the data structure for our new server object self::$current->ref1 = LigminchaGlobalServer::getCurrent()->id; self::$current->tag = self::getBrowser(); // Session only lives for five seconds in this initial form and doesn't route self::$current->expire = self::timestamp() + 2; self::$current->flag(LG_LOCAL, true); self::$current->flag(LG_PRIVATE, true); // Save our new instance to the DB $update = true; // And save the ID in the SSO cookie LigminchaGlobalSSO::setCookie(self::$current->id); lgDebug('New session created and SSO cookie set', self::$current); } else { self::$current = false; } } // Update the expiry if the session existed (but only if it's increasing by more than a minute to avoid sync traffic) if (self::$current && !self::$current->flag(LG_NEW)) { $expiry = self::timestamp() + LG_SESSION_DURATION; if ($expiry - self::$current->expire > 60) { self::$current->expire = $expiry; $update = true; } } // Avoid multiple calls to update above if ($update) { self::$current->update(); } return self::$current; }
<?php // Load the code common to standalone functionality include __DIR__ . '/standalone.php'; // These are the global objects made initially available to the app (only server objects are available if not logged in) $types = array(LG_SERVER, LG_LOG); if ($session) { $types[] = LG_USER; $types[] = LG_SESSION; } $objects = LigminchaGlobalObject::select(array('type' => $types)); $wgOut->addJsConfigVars('GlobalObjects', $objects); $wgOut->addJsConfigVars('toolbar', false); // Make the ID of the master server known to the client-side $wgOut->addJsConfigVars('masterServer', LigminchaGlobalServer::getMaster()->id); // Get the list of tags from the Github repo $config = JFactory::getConfig(); $auth = $config->get('lgRepoAuth'); $repoTags = array(); //json_decode( LigminchaGlobalDistributed::get( 'https://api.github.com/repos/Ligmincha/Code/tags', $auth ) ); $tags = array(); foreach ($repoTags as $tag) { if (preg_match('/^v([0-9.]+)/', $tag->name)) { $tags[$tag->name] = $tag->tarball_url; } } $wgOut->addJsConfigVars('tags', $tags); ?> <!DOCTYPE html> <html lang="en"> <head>
/** * Render an iFrame that requests the global toolbar */ public static function toolbar() { // Get the url of the global app $config = JFactory::getConfig(); $lgGlobalAppDomain = $config->get('lgGlobalApp', 'global.ligmincha.org'); // Include the code to render the toolbar require __DIR__ . '/toolbar.php'; // Add the toolbar to the body if we have a user $app = JFactory::getApplication('site'); $page = $app->getBody(); // Add the toolbar head code into the page head area $page = str_replace('</head>', "{$lgToolbarHead}\n</head>", $page); // Add the toolbar body code into start of the page body $page = preg_replace('#<body.*?>#', "\$0\n{$lgToolbarBody}", $page); // Set the image to the currently selected header (tempprary: fake template updating demo) $data = LigminchaGlobalServer::getCurrent()->data; $template = array_key_exists('template', $data) ? $data['template'] : 'maple'; $page = preg_replace('#(?<=src="images/headers/)(.+?)(?=\\.jpg")#', $template, $page); lgDebug("Template set to \"{$template}\""); // Update the page content $app->setBody($page); lgDebug("Global toolbar added to Joomla page"); }
/** * Receive sync-object queue from a remote server */ private static function recvQueue($data) { // Decode the data $queue = $orig = self::decodeData($data); if (!is_array($queue)) { die(lgDebug("Problem with received sync data: {$data}")); } $ip = array_shift($queue); $origin = array_shift($queue); $session = array_shift($queue); // If we're the master, forward this queue to the WebSocket if it's active if (LigminchaGlobalServer::getCurrent()->isMaster) { self::sendToWebSocket($orig, $session); } // Process each of the sync objects (this may lead to further re-routing sync objects being made) foreach ($queue as $sync) { LigminchaGlobalSync::process($sync['tag'], $sync['data'], $origin); } // Let client know that we've processed their sync data lgDebug('Sync data processed, returning "ok"'); return 'ok'; }
/** * Get/create current object instance */ public static function getCurrent() { if (is_null(self::$current)) { // Make a new uuid from the server's secret $config = JFactory::getConfig(); $id = self::hash($config->get('secret')); self::$current = self::newFromId($id); // If the object was newly created, populate with default initial data and save if (!self::$current->tag) { lgDebug('Server object created', self::$current); // Make it easy to find this server by domain self::$current->tag = $_SERVER['HTTP_HOST']; // Server information self::$current->data = self::serverData(); // Save our new instance to the DB (if we have a master yet) if (self::$master) { self::$current->update(); lgDebug('Server object updated', self::$master); } else { self::$deferred = true; lgDebug('Server object update deferred, master unknown'); } } else { lgDebug('Server object retrieved from database', self::$current); } } // If we have a master and we're not in standalone, ensure the server data is up to date if (self::$master && !LG_STANDALONE) { static $checked = false; if (!$checked) { $checked = true; if (json_encode(self::$current->data) !== json_encode(self::serverData(self::$current->data))) { self::$current->data = self::serverData(self::$current->data); self::$current->update(); } } } return self::$current; }
/** * Create outgoing sync objects(s) from local changes or for re-routing * * Make one or more sync objects depending on the context of this change * - The sync re-routing logic is in here * - $origin is the server the change came from if set * - $private is the owner's server if set */ public static function create($crud, $fields, $origin, $private = false) { $server = LigminchaGlobalServer::getCurrent(); // Origin is set if this change is the result of a received foreign sync object if ($origin) { // This is the only condition for which re-routing ever occurs if ($server->isMaster && $private === false) { // Create targetted sync objects for all except self and origin foreach (LigminchaGlobalServer::select() as $s) { if ($s->id != $server->id && $s->id != $origin) { new LigminchaGlobalSync($crud, $fields, $s); } } } } else { // If this is the master, then targets depend whether its private or not if ($server->isMaster) { // If private then we just have a single targetted sync object to the owner if ($private) { new LigminchaGlobalSync($crud, $fields, $private); } else { foreach (LigminchaGlobalServer::select() as $s) { if ($s->id != $server->id) { new LigminchaGlobalSync($crud, $fields, $s); } } } } else { new LigminchaGlobalSync($crud, $fields, LigminchaGlobalServer::getMaster()); } } }