Example #1
0
function Streams_after_Q_objects()
{
    $user = Users::loggedInUser();
    if (!$user) {
        return;
    }
    $invite = Streams::$followedInvite;
    if (!$invite) {
        return;
    }
    $displayName = $user->displayName();
    if ($displayName) {
        return;
    }
    $stream = new Streams_Stream();
    $stream->publisherId = $invite->publisherId;
    $stream->name = $invite->streamName;
    if (!$stream->retrieve()) {
        throw new Q_Exception_MissingRow(array('table' => 'stream', 'criteria' => 'with that name'), 'streamName');
    }
    // Prepare the complete invite dialog
    $invitingUser = Users_User::fetch($invite->invitingUserId);
    list($relations, $related) = Streams::related($user->id, $stream->publisherId, $stream->name, false);
    $params = array('displayName' => null, 'action' => 'Streams/basic', 'icon' => $user->iconUrl(), 'token' => $invite->token, 'user' => array('icon' => $invitingUser->iconUrl(), 'displayName' => $invitingUser->displayName(array('fullAccess' => true))), 'stream' => $stream->exportArray(), 'relations' => Db::exportArray($relations), 'related' => Db::exportArray($related));
    $config = Streams_Stream::getConfigField($stream->type, 'invite', array());
    $defaults = Q::ifset($config, 'dialog', array());
    $tree = new Q_Tree($defaults);
    if ($tree->merge($params)) {
        $dialogData = $tree->getAll();
        if ($dialogData) {
            Q_Response::setScriptData('Q.plugins.Streams.invite.dialog', $dialogData);
            Q_Response::addTemplate('Streams/invite/complete');
        }
    }
}
Example #2
0
function Streams_interests_response()
{
    // serve a javascript file and tell client to cache it
    $app = Q_Config::expect('Q', 'app');
    $communityId = Q::ifset($_REQUEST, 'communityId', $app);
    $tree = new Q_Tree();
    $tree->load("files/Streams/interests/{$communityId}.json");
    $categories = $tree->getAll();
    foreach ($categories as $category => &$v1) {
        foreach ($v1 as $k2 => &$v2) {
            if (!Q::isAssociative($v2)) {
                ksort($v1);
                break;
            }
            ksort($v2);
        }
    }
    header('Content-Type: text/javascript');
    header("Pragma: ", true);
    // 1 day
    header("Cache-Control: public, max-age=86400");
    // 1 day
    $expires = date("D, d M Y H:i:s T", time() + 86400);
    header("Expires: {$expires}");
    // 1 day
    $json = Q::json_encode($categories, true);
    echo "Q.setObject(['Q', 'Streams', 'Interests', 'all', '{$communityId}'], {$json});";
    return false;
}
Example #3
0
/**
 * Post one or more fields here to change the corresponding basic streams for the logged-in user. Fields can include:
 * "firstName": specify the first name directly
 * "lastName": specify the last name directly
 * "fullName": the user's full name, which if provided will be split into first and last name and override them
 * "gender": the user's gender
 * "birthday_year": the year the user was born
 * "birthday_month": the month the user was born
 * "birthday_day": the day the user was born
 */
function Streams_basic_post()
{
    Q_Valid::nonce(true);
    $user = Users::loggedInUser(true);
    $request = $_REQUEST;
    $fields = array();
    if (!empty($request['birthday_year']) && !empty($request['birthday_month']) && !empty($request['birthday_day'])) {
        $request['birthday'] = sprintf("%04d-%02d-%02d", $_REQUEST['birthday_year'], $_REQUEST['birthday_month'], $_REQUEST['birthday_day']);
    }
    //	$request['icon'] = $user->icon;
    if (isset($request['fullName'])) {
        $name = Streams::splitFullName($request['fullName']);
        $request['firstName'] = $name['first'];
        $request['lastName'] = $name['last'];
    }
    foreach (array('firstName', 'lastName', 'birthday', 'gender') as $field) {
        if (isset($request[$field])) {
            $fields[] = $field;
        }
    }
    $p = new Q_Tree();
    $p->load(STREAMS_PLUGIN_CONFIG_DIR . DS . 'streams.json');
    $p->load(APP_CONFIG_DIR . DS . 'streams.json');
    $names = array();
    foreach ($fields as $field) {
        $names[] = "Streams/user/{$field}";
    }
    $streams = Streams::fetch($user, $user->id, $names);
    foreach ($fields as $field) {
        $name = "Streams/user/{$field}";
        $type = $p->get($name, "type", null);
        if (!$type) {
            throw new Q_Exception("Missing {$name} type", $field);
        }
        $title = $p->get($name, "title", null);
        if (!$title) {
            throw new Q_Exception("Missing {$name} title", $field);
        }
        $stream = $streams[$name];
        if (isset($stream) and $stream->content === (string) $request[$field]) {
            continue;
        }
        if (!isset($stream)) {
            $stream = new Streams_Stream();
            $stream->publisherId = $user->id;
            $stream->name = $name;
        }
        $messageType = $stream->wasRetrieved() ? 'Streams/changed' : 'Streams/created';
        $stream->content = (string) $request[$field];
        $stream->type = $type;
        $stream->title = $title;
        $stream->changed($user->id, $messageType);
    }
}
function Streams_after_Users_User_saveExecute($params)
{
    // If the username or icon was somehow modified,
    // update all the avatars for this publisher
    $modifiedFields = $params['modifiedFields'];
    $user = $params['row'];
    $updates = array();
    if (isset($modifiedFields['username'])) {
        $updates['username'] = $modifiedFields['username'];
    }
    if (isset($modifiedFields['icon'])) {
        $updates['icon'] = $modifiedFields['icon'];
    }
    if ($user->id === Users::communityId()) {
        $firstName = Users::communityName();
        $lastName = Users::communitySuffix();
        $firstName = $firstName ? $firstName : "";
        $lastName = $lastName ? $lastName : "";
    } else {
        $firstName = Q::ifset(Streams::$cache, 'register', 'first', '');
        $lastName = Q::ifset(Streams::$cache, 'register', 'last', '');
    }
    if ($params['inserted']) {
        // create some standard streams for them
        $onInsert = Q_Config::get('Streams', 'onInsert', 'Users_User', array());
        if (!$onInsert) {
            return;
        }
        $p = new Q_Tree();
        $p->load(STREAMS_PLUGIN_CONFIG_DIR . DS . 'streams.json');
        $p->load(APP_CONFIG_DIR . DS . 'streams.json');
        $values = array('Streams/user/firstName' => $firstName, 'Streams/user/lastName' => $lastName);
        // Check for user data from facebook
        if (!empty(Users::$cache['facebookUserData'])) {
            $userData = Users::$cache['facebookUserData'];
            foreach ($userData as $name_fb => $value) {
                foreach ($p->getAll() as $name => $info) {
                    if (isset($info['name_fb']) and $info['name_fb'] === $name_fb) {
                        $onInsert[] = $name;
                        $values[$name] = $value;
                    }
                }
            }
        }
        foreach ($onInsert as $name) {
            $stream = Streams::fetchOne($user->id, $user->id, $name);
            if (!$stream) {
                // it shouldn't really be in the db yet
                $stream = new Streams_Stream();
                $stream->publisherId = $user->id;
                $stream->name = $name;
            }
            $stream->type = $p->expect($name, "type");
            $stream->title = $p->expect($name, "title");
            $stream->content = $p->get($name, "content", '');
            // usually empty
            $stream->readLevel = $p->get($name, 'readLevel', Streams_Stream::$DEFAULTS['readLevel']);
            $stream->writeLevel = $p->get($name, 'writeLevel', Streams_Stream::$DEFAULTS['writeLevel']);
            $stream->adminLevel = $p->get($name, 'adminLevel', Streams_Stream::$DEFAULTS['adminLevel']);
            if ($name === "Streams/user/icon") {
                $sizes = Q_Config::expect('Users', 'icon', 'sizes');
                sort($sizes);
                $stream->setAttribute('sizes', $sizes);
                $stream->icon = $user->iconUrl();
            }
            if (isset($values[$name])) {
                $stream->content = $values[$name];
            }
            $stream->save();
            // this also inserts avatars
            $o = array('userId' => $user->id, 'skipAccess' => true);
            $so = $p->get($name, "subscribe", array());
            if ($so === false) {
                $stream->join($o);
            } else {
                $stream->subscribe(array_merge($o, $so));
            }
        }
        // Save a greeting stream, to be edited
        $communityId = Users::communityId();
        Streams::create($user->id, $user->id, "Streams/greeting", array('name' => "Streams/greeting/{$communityId}"));
        // Create some standard labels
        $label = new Users_Label();
        $label->userId = $user->id;
        $label->label = 'Streams/invited';
        $label->icon = 'labels/Streams/invited';
        $label->title = 'People I invited';
        $label->save(true);
        $label2 = new Users_Label();
        $label2->userId = $user->id;
        $label2->label = 'Streams/invitedMe';
        $label2->icon = 'labels/Streams/invitedMe';
        $label2->title = 'Who invited me';
        $label2->save(true);
        // By default, users they invite should see their full name
        $access = new Streams_Access();
        $access->publisherId = $user->id;
        $access->streamName = 'Streams/user/firstName';
        $access->ofUserId = '';
        $access->ofContactLabel = 'Streams/invited';
        $access->grantedByUserId = $user->id;
        $access->readLevel = Streams::$READ_LEVEL['content'];
        $access->writeLevel = -1;
        $access->adminLevel = -1;
        $access->save();
        $access = new Streams_Access();
        $access->publisherId = $user->id;
        $access->streamName = 'Streams/user/lastName';
        $access->ofUserId = '';
        $access->ofContactLabel = 'Streams/invited';
        $access->grantedByUserId = $user->id;
        $access->readLevel = Streams::$READ_LEVEL['content'];
        $access->writeLevel = -1;
        $access->adminLevel = -1;
        $access->save();
        // NOTE: the above saving of access caused Streams::updateAvatar to run,
        // insert a Streams_Avatar row for the new user, and properly configure it.
    } else {
        if ($modifiedFields) {
            if ($updates) {
                Streams_Avatar::update()->set($updates)->where(array('publisherId' => $user->id))->execute();
            }
            foreach ($modifiedFields as $field => $value) {
                $name = Q_Config::get('Streams', 'onUpdate', 'Users_User', $field, null);
                if (!$name) {
                    continue;
                }
                $stream = isset(Streams::$beingSaved[$field]) ? Streams::$beingSaved[$field] : Streams::fetchOne($user->id, $user->id, $name);
                if (!$stream) {
                    // it should probably already be in the db
                    continue;
                }
                $stream->content = $value;
                if ($name === "Streams/user/icon") {
                    $sizes = Q_Config::expect('Users', 'icon', 'sizes');
                    sort($sizes);
                    $attributes = $stream->attributes;
                    $stream->setAttribute('sizes', $sizes);
                    $stream->icon = $changes['icon'] = $user->iconUrl();
                }
                Streams::$beingSavedQuery = $stream->changed($user->id);
            }
        }
    }
}
Example #5
0
 /**
  * Clears the value of a field, possibly deep inside the array
  * @method clear
  * @param {string} $key1 The name of the first key in the configuration path
  * @param {string} $key2 Optional. The name of the second key in the configuration path.
  *  You can actually pass as many keys as you need,
  *  delving deeper and deeper into the configuration structure.
  *  All but the second-to-last parameter are interpreted as keys.
  */
 function clear($key1)
 {
     if (!isset($key1)) {
         $this->parameters = self::$cache = array();
         return;
     }
     $args = func_get_args();
     $args_count = func_num_args();
     $result =& $this->parameters;
     for ($i = 0; $i < $args_count - 1; ++$i) {
         $key = $args[$i];
         if (!is_array($result) or !array_key_exists($key, $result)) {
             return false;
         }
         $result =& $result[$key];
     }
     // clear the final value
     $key = $args[$args_count - 1];
     if (isset($key)) {
         unset($result[$key]);
     } else {
         array_pop($result);
     }
 }
Example #6
0
 /**
  * Loads the configuration and plugins in the right order
  * @method configure
  * @static
  * @param boolean [$force_reload=false] If true, forces the reload of the cache.
  *  Otherwise it happens only if Q/configServer/interval seconds
  *  have passed since the last time.
  * @throws {Q_Exception_MissingPlugin}
  */
 static function configure($force_reload = false)
 {
     $app_tree = new Q_Tree();
     // check if config need to be reloaded
     if (Q_Cache::connected()) {
         // we need to know reload interval
         $app_tree->load('config/Q.json');
         $app_tree->load('config/app.json');
         $app_tree->load('local/app.json');
         $config_files = $app_tree->get('Q', 'configFiles', array());
         foreach ($config_files as $cf) {
             $app_tree->merge(Q_Config::getFromServer($cf));
         }
         // second round to catch configFiles inside configFiles
         $config_files = $app_tree->get('Q', 'configFiles', array());
         foreach ($config_files as $cf) {
             $app_tree->merge(Q_Config::getFromServer($cf));
         }
         $interval = $app_tree->get('Q', 'configServer', 'interval', 60);
         // reload each minute by default
         $app_tree->clear(null);
         $timestamp = Q_Cache::get("Q_Config\tupdate_time");
         if (!isset($timestamp) || time() - $timestamp > $interval) {
             $force_reload = true;
         }
     }
     if ($force_reload) {
         $old_setting = Q_Cache::ignore(true);
     }
     Q_Config::clear(null);
     // clear the config
     Q_Config::load('config/Q.json');
     // Get the app config, but don't load it yet
     $app_tree->load('config/app.json');
     $app_tree->load('local/app.json');
     // Load all the plugin config files first
     $paths = explode(PS, get_include_path());
     $plugins = $app_tree->get('Q', 'plugins', array());
     if (!in_array('Q', $plugins)) {
         array_unshift($plugins, 'Q');
     }
     global $Q_Bootstrap_config_plugin_limit;
     $i = 0;
     foreach ($plugins as $k => $v) {
         ++$i;
         if (isset($Q_Bootstrap_config_plugin_limit) and $i > $Q_Bootstrap_config_plugin_limit) {
             continue;
         }
         $plugin = is_numeric($k) ? $v : $k;
         $plugin_path = Q::realPath('plugins' . DS . $v);
         if (!$plugin_path) {
             throw new Q_Exception_MissingPlugin(compact('plugin'));
         }
         Q_Config::load($plugin_path . DS . 'config' . DS . 'plugin.json');
         array_splice($paths, 1, 0, array($plugin_path));
         $PLUGIN = strtoupper($plugin);
         if (!defined($PLUGIN . '_PLUGIN_DIR')) {
             define($PLUGIN . '_PLUGIN_DIR', $plugin_path);
         }
         if (!defined($PLUGIN . '_PLUGIN_CONFIG_DIR')) {
             define($PLUGIN . '_PLUGIN_CONFIG_DIR', $plugin_path . DS . 'config');
         }
         if (!defined($PLUGIN . '_PLUGIN_CLASSES_DIR')) {
             define($PLUGIN . '_PLUGIN_CLASSES_DIR', $plugin_path . DS . 'classes');
         }
         if (!defined($PLUGIN . '_PLUGIN_FILES_DIR')) {
             define($PLUGIN . '_PLUGIN_FILES_DIR', $plugin_path . DS . 'files');
         }
         if (!defined($PLUGIN . '_PLUGIN_HANDLERS_DIR')) {
             define($PLUGIN . '_PLUGIN_HANDLERS_DIR', $plugin_path . DS . 'handlers');
         }
         if (!defined($PLUGIN . '_PLUGIN_PLUGINS_DIR')) {
             define($PLUGIN . '_PLUGIN_PLUGINS_DIR', $plugin_path . DS . 'plugins');
         }
         if (!defined($PLUGIN . '_PLUGIN_SCRIPTS_DIR')) {
             define($PLUGIN . '_PLUGIN_SCRIPTS_DIR', $plugin_path . DS . 'scripts');
         }
         if (!defined($PLUGIN . '_PLUGIN_VIEWS_DIR')) {
             define($PLUGIN . '_PLUGIN_VIEWS_DIR', $plugin_path . DS . 'views');
         }
         if (!defined($PLUGIN . '_PLUGIN_TESTS_DIR')) {
             define($PLUGIN . '_PLUGIN_TESTS_DIR', $plugin_path . DS . 'tests');
         }
         if (!defined($PLUGIN . '_PLUGIN_WEB_DIR')) {
             define($PLUGIN . '_PLUGIN_WEB_DIR', $plugin_path . DS . 'web');
         }
         self::$plugins[$plugin] = $plugin_path;
     }
     $paths = array_unique($paths);
     set_include_path(implode(PS, $paths));
     // Now, we can merge in our app's config
     Q_Config::merge($app_tree);
     // Now, load any other files we were supposed to load
     $config_files = Q_Config::get('Q', 'configFiles', array());
     foreach ($config_files as $cf) {
         Q_Config::merge(Q_Config::getFromServer($cf));
     }
     // second round to catch configFiles inside configFiles
     $config_files = Q_Config::get('Q', 'configFiles', array());
     foreach ($config_files as $cf) {
         Q_Config::merge(Q_Config::getFromServer($cf));
     }
     $script_files = Q_Config::get('Q', 'scriptFiles', array());
     foreach ($script_files as $cf) {
         Q::includeFile($cf);
     }
     error_reporting(Q_Config::get('Q', 'errorReporting', E_ALL));
     if (isset($old_setting)) {
         Q_Cache::ignore($old_setting);
     }
     set_time_limit(Q_Config::get('Q', 'internal', 'phpTimeout', 30));
     self::setDefaultTimezone();
 }
Example #7
0
 /**
  * Creates a new stream in the system
  * @method create
  * @static
  * @param {string} $asUserId The user who is attempting to create the stream.
  * @param {string} $publisherId The id of the user to publish the stream.
  * @param {string} $type The type of the stream to create.
  * @param {array} $fields Use this to set additional fields for the stream:
  * @param {string} [$fields.title=null] You can set the stream's title
  * @param {string} [$fields.icon=null] You can set the stream's icon
  * @param {string} [$fields.title=null] You can set the stream's content
  * @param {string} [$fields.attributes=null] You can set the stream's attributes directly as a JSON string
  * @param {string|integer} [$fields.readLevel=null] You can set the stream's read access level, see Streams::$READ_LEVEL
  * @param {string|integer} [$fields.writeLevel=null] You can set the stream's write access level, see Streams::$WRITE_LEVEL
  * @param {string|integer} [$fields.adminLevel=null] You can set the stream's admin access level, see Streams::$ADMIN_LEVEL
  * @param {string} [$fields.name=null] Here you can specify an exact name for the stream to be created. Otherwise a unique one is generated automatically.
  * @param {boolean} [$fields.skipAccess=false] Skip all access checks when creating and relating the stream.
  * @param {array} [$relate=array()]
  *  The user would also be authorized if the stream would be related to
  *  an existing category stream, in which the user has a writeLevel of at least "relate",
  *  and the user that would be publishing this new stream has a template for this stream type
  *  that is related to either the category stream or a template matching the category stream.
  *  To test for this, pass an array with the following keys:
  * @param {string} $relate.publisherId The id of the user publishing that stream, defaults to $publisherId
  * @param {string} $relate.streamName The name of the stream to which the new stream would be related
  * @param {string} [$relate.type] The type of relation, defaults to ""
  * @param {string} [$relate.weight] To set the weight for the relation
  * @return {Streams_Stream|boolean} Returns the stream that was created.
  * @throws {Users_Exception_NotAuthorized}
  */
 static function create($asUserId, $publisherId, $type, $fields = array(), $relate = null)
 {
     $skipAccess = Q::ifset($fields, 'skipAccess', false);
     if (!isset($asUserId)) {
         $asUserId = Users::loggedInUser();
         if (!$asUserId) {
             $asUserId = "";
         }
     }
     if ($asUserId instanceof Users_User) {
         $asUserId = $asUserId->id;
     }
     if ($publisherId instanceof Users_User) {
         $publisherId = $publisherId->id;
     }
     $authorized = self::isAuthorizedToCreate($asUserId, $publisherId, $type, $relate);
     if (!$authorized and !$skipAccess) {
         throw new Users_Exception_NotAuthorized();
     }
     // OK we are good to go!
     $stream = new Streams_Stream();
     $stream->publisherId = $publisherId;
     if (!empty($fields['name'])) {
         $p = new Q_Tree();
         $p->load(STREAMS_PLUGIN_CONFIG_DIR . DS . 'streams.json');
         $p->load(APP_CONFIG_DIR . DS . 'streams.json');
         if ($info = $p->get($fields['name'], array())) {
             foreach (Base_Streams_Stream::fieldNames() as $f) {
                 if (isset($info[$f])) {
                     $stream->{$f} = $info[$f];
                 }
             }
         }
     }
     if (!isset($stream->type)) {
         $stream->type = $type;
     }
     // prepare attributes field
     if (isset($fields['attributes']) and is_array($fields['attributes'])) {
         $fields['attributes'] = json_encode($fields['attributes']);
     }
     // extend with any config defaults for this stream type
     $fieldNames = Streams::getExtendFieldNames($type);
     $fieldNames[] = 'name';
     $defaults = Q_Config::get('Streams', 'types', $type, 'defaults', array());
     foreach ($fieldNames as $f) {
         if (isset($fields[$f])) {
             $stream->{$f} = $fields[$f];
         } else {
             if (array_key_exists($f, $defaults)) {
                 $stream->{$f} = $defaults[$f];
             }
         }
     }
     // ready to persist this stream to the database
     if ($relate['streamName']) {
         $rs = Streams::fetchOne($asUserId, $relate['publisherId'], $relate['streamName']);
         if ($rs and $rs->inheritAccess) {
             // inherit from the same stream $rs does
             $inherit = $rs->inheritAccess;
         } else {
             // inherit from $rs
             $json = Q::json_encode(array(array($relate['publisherId'], $relate['streamName'])));
         }
         $stream->inheritAccess = $json;
     }
     $stream->save();
     $stream->post($asUserId, array('type' => 'Streams/created', 'content' => '', 'instructions' => Q::json_encode($stream->toArray())), true);
     // relate the stream to category stream, if any
     if ($relate['streamName']) {
         $result = Streams::relate($asUserId, $relate['publisherId'], $relate['streamName'], $relate['type'], $stream->publisherId, $stream->name, array('weight' => isset($relate['weight']) ? $relate['weight'] : null, 'skipAccess' => $skipAccess));
         Q_Response::setSlot('messageTo', $result['messageTo']->exportArray());
     }
     self::$fetch[$asUserId][$publisherId][$stream->name] = array('*' => $stream);
     return $stream;
 }
Example #8
0
 /**
  * Modify a config file by clearing some data
  * Config file is searched in APP_DIR/files forder. If config server url is defined
  * the filename is searched on config server
  * @method clearOnServer
  * @static
  * @param {string} $filename The name of the config file. If config server is defined, file is changed there
  * @param {string|array} [$args=null] OA key or an array of keys for traversing the tree.
  *	If keys are not supplied the file is cleared
  *	If all-but-last keys point to plain array, last key is interpreted as a member
  *	of that array and only this array member is removed
  *	If all-but-last keys point to associative array (A) and last key is plain array (B)
  *	all keys from array A which are in array B are unset
  * @param {boolean} [$noSave=false] Weather result shall be returned or saved. Shall be of type boolean
  * @return {boolean} Wheather data was successfuly cleared. If some key does not exist still true
  * @throws {Q_Exception}
  */
 static function clearOnServer($filename, $args = null, $noSave = false)
 {
     if (!isset($args) || $args === 'null') {
         $args = array();
     }
     if (is_string($args)) {
         $args = array($args);
     }
     if (is_string($noSave)) {
         $noSave = json_decode($noSave);
     }
     $noSave = !!$noSave;
     if ($cs = self::serverInfo()) {
         // request config server
         if (!empty($cs['url'])) {
             if (!empty($cs['internal'])) {
                 // query "internal" Qbix server
                 return Q_Utils::queryInternal('Q/Config', array('Q/method' => 'clear', 'filename' => $filename, 'args' => $args, 'noSave' => $noSave), $cs['url']);
             } else {
                 // query "external" Qbix server
                 return Q_Utils::queryExternal('Q/Config', array('Q/method' => 'clear', 'filename' => $filename, 'args' => $args, 'noSave' => $noSave), $cs['url']);
             }
         }
     }
     // modify local file
     if (defined('APP_DIR')) {
         $filename = Q::realPath(APP_DIR . DS . 'files' . DS . $filename);
     } else {
         throw new Q_Exception("'APP_DIR' is not defined");
     }
     if (!$filename) {
         return true;
     }
     $tree = new Q_Tree();
     if (count($args)) {
         $tree->load($filename);
         // if not loaded we consider three empty
         if (count($args) > 1) {
             $last = call_user_func_array(array($tree, "get"), $args);
         } else {
             $last = $tree->getAll();
         }
         if (is_array($last)) {
             if (array_keys($last) === range(0, count($last) - 1)) {
                 // it's plain array and we remove it's member
                 $search = array_pop($args);
                 if (!is_array($search)) {
                     $search = array($search);
                 }
                 foreach ($search as $value) {
                     $keys = array_keys($last, $value);
                     for ($deleted = 0, $i = 0; $i < count($keys); $i++) {
                         array_splice($last, $keys[$i] - $deleted++, 1);
                     }
                 }
                 call_user_func_array(array($tree, "clear"), $args);
                 if (count($last)) {
                     array_push($args, $last);
                     call_user_func_array(array($tree, "set"), $args);
                 }
             } else {
                 // $last is associative array
                 $search = array_pop($args);
                 if (!is_array($search)) {
                     $search = array($search);
                 }
                 foreach ($search as $value) {
                     call_user_func_array(array($tree, "clear"), array_merge($args, array($value)));
                 }
             }
         }
     } else {
         $tree = new Q_Tree();
     }
     return $noSave ? $tree->getAll() : $tree->save($filename);
 }
Example #9
0
if (!is_dir($LOCAL_DIR)) {
    #App dir
    die("[ERROR] {$LOCAL_DIR} doesn't exist or is not a directory" . PHP_EOL);
}
#Define APP_DIR
if (!defined('APP_DIR')) {
    define('APP_DIR', $LOCAL_DIR);
}
#Include Q
try {
    include $Q_filename;
} catch (Exception $e) {
    die('[ERROR] ' . $e->getMessage() . PHP_EOL . $e->getTraceAsString() . PHP_EOL);
}
#Parse secondary arguments
$config = new Q_Tree();
$mode = '';
for ($i = $FROM_APP ? 1 : 2; $i < $count; ++$i) {
    switch ($mode) {
        case 'part':
            $part = explode('/', $argv[$i]);
            if (count($part) < 2) {
                echo "Not enough parameters to {$argv[$i]} option\n{$usage}";
                exit;
            }
            $config->set('plugin', $part[0]);
            $config->set('table', $part[1]);
            if (isset($part[2])) {
                $config->set('shard', $part[2]);
            }
            $mode = '';
Example #10
0
 /**
  * Get a structured, sorted array with all the interests in a community
  * @method interests
  * @static
  * @param {string} [$communityId=Users::communityId()] the id of the community
  * @return {array} an array of $category => ($subcategory =>) $interest
  */
 static function interests($communityId = null)
 {
     if (!isset($communityId)) {
         $communityId = Users::communityId();
     }
     $tree = new Q_Tree();
     $tree->load("files/Streams/interests/{$communityId}.json");
     $interests = $tree->getAll();
     foreach ($interests as $category => &$v1) {
         foreach ($v1 as $k2 => &$v2) {
             if (!Q::isAssociative($v2)) {
                 ksort($v1);
                 break;
             }
             ksort($v2);
         }
     }
     return $interests;
 }
Example #11
0
 /**
  * @method writeHandler
  * @static
  * @param {string} $id
  * @param {string} $sess_data
  * @return {boolean}
  */
 static function writeHandler($id, $sess_data)
 {
     try {
         // if the request is AJAX request that came without session cookie, then do not write session, ignore it
         if (Q_Request::isAjax() && !isset($_COOKIE[self::name()])) {
             return false;
         }
         // don't save sessions when running from command-line (cli)
         if (php_sapi_name() == 'cli') {
             return false;
         }
         $our_SESSION = $_SESSION;
         $old_data = self::$sess_data;
         $changed = $sess_data !== $old_data;
         $result = false;
         /**
          * @event Q/session/write {before}
          * @param {string} id
          * @param {string} sess_data
          * @param {string} old_data
          * @param {boolean} changed
          * @return {boolean}
          */
         if (false === Q::event('Q/session/write', compact('id', 'sess_data', 'old_data', 'changed'), 'before')) {
             return false;
         }
         if (empty(self::$session_save_path)) {
             self::$session_save_path = self::savePath();
         }
         if (!empty(self::$session_db_connection)) {
             // Create a new row to be saved in the session table
             $db_row_class = self::$session_db_row_class;
             // Make sure it has a primary key!
             if (count(self::$session_db_row->getPrimaryKey()) != 1) {
                 throw new Q_Exception("The primary key of " . self::$session_db_row_class . " has to consist of exactly 1 field!");
             }
             $id_field = self::$session_db_id_field;
             $data_field = self::$session_db_data_field;
             $updated_field = self::$session_db_updated_field;
             $duration_field = self::$session_db_duration_field;
             $row = self::$session_db_row;
             $row->{$id_field} = $id;
         } else {
             $duration_name = self::durationName();
             $id1 = substr($id, 0, 4);
             $id2 = substr($id, 4);
             $ssp = self::$session_save_path;
             $sess_file = $ssp . DS . "{$duration_name}/{$id1}/{$id2}";
             $dir = $ssp . DS . "{$duration_name}/{$id1}/";
         }
         if ($changed) {
             // Apparently, we want to save some changes.
             // The convention to avoid locking is that everything
             // stored in sessions must be mergeable using the
             // Q_Tree merge algorithm.
             // So we will retrieve the latest session data again,
             // merge our changes over it, and save.
             $params = array('id_field' => $id_field, 'data_field' => $data_field, 'updated_field' => $updated_field, 'duration_field' => $duration_field, 'changed' => $changed, 'sess_data' => $sess_data, 'old_data' => $old_data);
             if (!empty(self::$session_db_connection)) {
                 $row->retrieve();
                 $existing_data = Q::ifset($row, $data_field, "");
                 $params['row'] = $row;
             } else {
                 if (!is_dir($dir)) {
                     mkdir($dir, fileperms($ssp), true);
                 }
                 if (!is_writable($dir)) {
                     // alert the developer to this problem
                     Q::log("{$sess_file} is not writable", 'fatal');
                     die("{$sess_file} is not writable");
                 }
                 $file = fopen($sess_file, "w");
                 if (!$file) {
                     return false;
                 }
                 $params['row'] = $row;
                 $maxlength = Q_Config::get('Q', 'session', 'maxlength', 4095);
                 $existing_data = fread($file, $maxlength);
             }
             $_SESSION = session_decode($existing_data);
             if (!$_SESSION) {
                 $_SESSION = array();
             }
             $t = new Q_Tree($_SESSION);
             $t->merge($our_SESSION);
             $_SESSION = $t->getAll();
             $params['existing_data'] = $existing_data;
             $params['merged_data'] = $merged_data = session_encode();
             /**
              * @event Q/session/save {before}
              * @param {string} sess_data
              * @param {string} old_data
              * @param {string} existing_data
              * @param {string} merged_data
              * @param {boolean} changed
              * @param {Db_Row} row
              * @return {boolean}
              */
             if (false === Q::event('Q/session/save', $params, 'before')) {
                 return false;
             }
             if (!empty(self::$session_db_connection)) {
                 $row->{$data_field} = $merged_data;
                 $row->{$duration_field} = Q_Config::get('Q', 'session', 'durations', Q_Request::formFactor(), Q_Config::expect('Q', 'session', 'durations', 'session'));
                 $row->save();
                 $result = true;
             } else {
                 $result = fwrite($file, $merged_data);
                 fclose($file);
             }
         }
         /**
          * @event Q/session/write {after}
          * @param {string} id
          * @param {boolean} changed
          * @param {string} sess_data
          * @param {string} old_data
          * @param {string} existing_data
          * @param {string} merged_data
          * @param {string} data_field
          * @param {string} updated_field
          * @param {string} duration_field
          * @param {string} sess_file
          * @param {integer} row
          * @return {mixed}
          */
         $result = Q::event('Q/session/write', compact('id', 'data_field', 'updated_field', 'duration_field', 'sess_file', 'row', 'changed', 'sess_data', 'old_data', 'existing_data', 'merged_data'), 'after');
         return $result;
     } catch (Exception $e) {
         Q::log("Exception when writing session {$id}: " . $e->getMessage());
         throw $e;
     }
 }