This class is intended to extend the $_SESSION magic variable by providing an API hook
to plug in other values.
Primarily this is intended to provide a way of supplying "logged in user" details without touching the session
(which can cause problems when accessed server side).
If a value is present in the session then that value is returned, otherwise a plugin hook 'session:get', '$var' is called,
where $var is the variable being requested.
Setting values will store variables in the session in the normal way.
LIMITATIONS: You can not access multidimensional arrays
This is EXPERIMENTAL.
/** * Update a specific piece of metadata. * * @param int $id ID of the metadata to update * @param string $name Metadata name * @param string $value Metadata value * @param string $value_type Value type * @param int $owner_guid Owner guid * @param int $access_id Access ID * * @return bool */ function update($id, $name, $value, $value_type, $owner_guid, $access_id) { $id = (int) $id; if (!($md = $this->get($id))) { return false; } if (!$md->canEdit()) { return false; } $value_type = detect_extender_valuetype($value, $this->db->sanitizeString(trim($value_type))); $owner_guid = (int) $owner_guid; if ($owner_guid == 0) { $owner_guid = $this->session->getLoggedInUserGuid(); } $access_id = (int) $access_id; // Support boolean types (as integers) if (is_bool($value)) { $value = (int) $value; } // If ok then add it $query = "UPDATE {$this->table}\n\t\t\tSET name = :name,\n\t\t\t value = :value,\n\t\t\t\tvalue_type = :value_type,\n\t\t\t\taccess_id = :access_id,\n\t\t\t owner_guid = :owner_guid\n\t\t\tWHERE id = :id"; $result = $this->db->updateData($query, false, [':name' => $name, ':value' => $value, ':value_type' => $value_type, ':access_id' => $access_id, ':owner_guid' => $owner_guid, ':id' => $id]); if ($result !== false) { $this->cache->clear($md->entity_guid); // @todo this event tells you the metadata has been updated, but does not // let you do anything about it. What is needed is a plugin hook before // the update that passes old and new values. $obj = $this->get($id); $this->events->trigger('update', 'metadata', $obj); } return $result; }
/** * Pull notification events from queue until stop time is reached * * @param int $stopTime The Unix time to stop sending notifications * @return int The number of notification events handled * @access private */ public function processQueue($stopTime) { $this->subscriptions->methods = $this->methods; $count = 0; // @todo grab mutex $ia = $this->session->setIgnoreAccess(true); while (time() < $stopTime) { // dequeue notification event $event = $this->queue->dequeue(); if (!$event) { break; } // test for usage of the deprecated override hook if ($this->existsDeprecatedNotificationOverride($event)) { continue; } $subscriptions = $this->subscriptions->getSubscriptions($event); // return false to stop the default notification sender $params = array('event' => $event, 'subscriptions' => $subscriptions); if ($this->hooks->trigger('send:before', 'notifications', $params, true)) { $this->sendNotifications($event, $subscriptions); } $this->hooks->trigger('send:after', 'notifications', $params); $count++; } // release mutex $this->session->setIgnoreAccess($ia); return $count; }
/** * Get a key to represent the access ability of the system. This is used to shard the cache array. * * @return string E.g. "ignored" or "123" */ protected function getAccessKey() { if ($this->session->getIgnoreAccess()) { return "ignored"; } return (string) $this->session->getLoggedInUserGuid(); }
/** * Constructor */ public function __construct() { $sp = _elgg_services(); $this->setValue('session', \ElggSession::getMock()); $this->setFactory('db', function (MockServiceProvider $m) use($sp) { $config = $this->getTestingDatabaseConfig(); return new \Elgg\Mocks\Database($config, $sp->logger); }); $this->setFactory('entityTable', function (MockServiceProvider $m) use($sp) { return new \Elgg\Mocks\Database\EntityTable($sp->config, $m->db, $sp->entityCache, $sp->metadataCache, $m->subtypeTable, $sp->events, $sp->session, $sp->translator, $sp->logger); }); $this->setFactory('metadataTable', function (MockServiceProvider $m) use($sp) { return new \Elgg\Mocks\Database\MetadataTable($sp->metadataCache, $m->db, $m->entityTable, $sp->events, $m->session); }); $this->setFactory('annotations', function (MockServiceProvider $m) use($sp) { return new \Elgg\Mocks\Database\Annotations($m->db, $m->session, $sp->events); }); $this->setFactory('relationshipsTable', function (MockServiceProvider $m) use($sp) { return new \Elgg\Mocks\Database\RelationshipsTable($m->db, $m->entityTable, $m->metadataTable, $sp->events); }); $this->setFactory('subtypeTable', function (MockServiceProvider $m) { return new \Elgg\Mocks\Database\SubtypeTable($m->db); }); $this->setFactory('accessCollections', function (MockServiceProvider $m) use($sp) { return new \Elgg\Mocks\Database\AccessCollections($sp->config, $m->db, $m->entityTable, $sp->accessCache, $sp->hooks, $sp->session, $sp->translator); }); $this->setFactory('privateSettings', function (MockServiceProvider $m) use($sp) { return new \Elgg\Mocks\Database\PrivateSettingsTable($m->db, $m->entityTable, $sp->pluginSettingsCache); }); }
public function setUp() { _elgg_filestore_init(); // we will need simpletype hook to work $this->hooks = new \Elgg\PluginHooksService(); $path_key = \Elgg\Application::GET_PATH_KEY; $this->request = \Elgg\Http\Request::create("?{$path_key}=action/upload"); $this->logger = new \Elgg\Logger($this->hooks, $this->config(), new \Elgg\Context()); $this->setupMockServices(false); $this->entities = _elgg_services()->entityTable; $this->user = $this->mocks()->getUser(); $this->entity = $this->mocks()->getObject(['owner_guid' => $this->user->guid, 'subtype' => 'foo']); $dir = (new \Elgg\EntityDirLocator($this->entity->guid))->getPath(); $this->entity_dir_path = $this->config()->get('dataroot') . $dir; if (is_dir($this->entity_dir_path)) { _elgg_rmdir($this->entity_dir_path); } $dir = (new \Elgg\EntityDirLocator($this->entity->owner_guid))->getPath(); $this->owner_dir_path = $this->config()->get('dataroot') . $dir; if (is_dir($this->owner_dir_path)) { _elgg_rmdir($this->owner_dir_path); } // Needed to test elgg_get_inline_url() $session = \ElggSession::getMock(); _elgg_services()->setValue('session', $session); _elgg_services()->session->start(); }
public function setUp() { // required by \ElggEntity when setting the owner/container _elgg_services()->setValue('session', \ElggSession::getMock()); $this->obj = $this->getMockBuilder('\\ElggUpgrade')->setMethods(null)->getMock(); $this->obj->_callable_egefps = array($this, 'mock_egefps'); }
/** * Sends a notice about deprecated use of a function, view, etc. * * @param string $msg Message to log / display. * @param string $dep_version Human-readable *release* version: 1.7, 1.8, ... * @param int $backtrace_level How many levels back to display the backtrace. * Useful if calling from functions that are called * from other places (like elgg_view()). Set to -1 * for a full backtrace. * @return bool */ function sendNotice($msg, $dep_version, $backtrace_level = 1) { // if it's a major release behind, visual and logged // if it's a 1 minor release behind, visual and logged // if it's for current minor release, logged. // bugfixes don't matter because we are not deprecating between them if (!$dep_version) { return false; } $elgg_version = elgg_get_version(true); $elgg_version_arr = explode('.', $elgg_version); $elgg_major_version = (int) $elgg_version_arr[0]; $elgg_minor_version = (int) $elgg_version_arr[1]; $dep_version_arr = explode('.', (string) $dep_version); $dep_major_version = (int) $dep_version_arr[0]; $dep_minor_version = (int) $dep_version_arr[1]; $visual = false; if ($dep_major_version < $elgg_major_version || $dep_minor_version < $elgg_minor_version) { $visual = true; } $msg = "Deprecated in {$dep_major_version}.{$dep_minor_version}: {$msg}"; if ($visual && $this->session->isAdminLoggedIn()) { register_error($msg); } // Get a file and line number for the log. Never show this in the UI. // Skip over the function that sent this notice and see who called the deprecated // function itself. $msg .= " Called from "; $stack = array(); $backtrace = debug_backtrace(); // never show this call. array_shift($backtrace); $i = count($backtrace); foreach ($backtrace as $trace) { $stack[] = "[#{$i}] {$trace['file']}:{$trace['line']}"; $i--; if ($backtrace_level > 0) { if ($backtrace_level <= 1) { break; } $backtrace_level--; } } $msg .= implode("<br /> -> ", $stack); $this->logger->warn($msg); return true; }
function testLegacyCookiesAreReplacedInDbCookieAndSession() { $this->svc = $this->getSvcWithCookie(str_repeat('a', 32)); $this->dbMock->expects($this->atLeastOnce())->method('deleteData'); $this->dbMock->expects($this->once())->method('insertData'); $this->svc->replaceLegacyToken($this->user123); $this->assertSame($this->mockToken, $this->lastCookieSet->value); $this->assertSame($this->mockToken, $this->session->get('code')); }
/** * Check to see if a user has already created an annotation on an object * * @param int $entity_guid Entity guid * @param string $annotation_type Type of annotation * @param int $owner_guid Defaults to logged in user. * * @return bool */ function exists($entity_guid, $annotation_type, $owner_guid = null) { if (!$owner_guid && !($owner_guid = $this->session->getLoggedInUserGuid())) { return false; } $sql = "SELECT id FROM {$this->db->prefix}annotations\n\t\t\t\tWHERE owner_guid = :owner_guid\n\t\t\t\tAND entity_guid = :entity_guid\n\t\t\t\tAND name = :annotation_type"; $result = $this->db->getDataRow($sql, null, [':owner_guid' => (int) $owner_guid, ':entity_guid' => (int) $entity_guid, ':annotation_type' => $annotation_type]); return (bool) $result; }
public function testMigrate() { $session = new ElggSession(new Elgg_Http_MockSessionStorage()); $session->start(); $session->set('foo', 5); $id = $session->getId(); $this->assertTrue($session->migrate()); $this->assertTrue($session->has('foo')); $this->assertNotEquals($id, $session->getId()); $this->assertTrue($session->has('__elgg_session')); }
public function setUp() { $this->hooks = new \Elgg\PluginHooksService(); $this->queue = new \Elgg\Queue\MemoryQueue(); $dbMock = $this->getMockBuilder('\\Elgg\\Database')->disableOriginalConstructor()->getMock(); $this->sub = new \Elgg\Notifications\SubscriptionsService($dbMock); $this->session = \ElggSession::getMock(); // Event class has dependency on elgg_get_logged_in_user_guid() _elgg_services()->setValue('session', $this->session); }
public function setUp() { $this->viewsDir = dirname(dirname(__FILE__)) . "/test_files/views"; $this->hooks = new \Elgg\PluginHooksService(); $this->logger = $this->getMock('\\Elgg\\Logger', array(), array(), '', false); $this->views = new \Elgg\ViewsService($this->hooks, $this->logger); $this->views->autoregisterViews('', "{$this->viewsDir}/default", 'default'); // supports deprecation wrapper for $vars['user'] _elgg_services()->setValue('session', \ElggSession::getMock()); }
protected function setUp() { _elgg_services()->setValue('session', \ElggSession::getMock()); $this->obj = $this->getMockForAbstractClass('\\ElggEntity'); $reflection = new ReflectionClass('\\ElggEntity'); $method = $reflection->getMethod('initializeAttributes'); if (method_exists($method, 'setAccessible')) { $method->setAccessible(true); $method->invokeArgs($this->obj, array()); } }
public function setUp() { $session = \ElggSession::getMock(); _elgg_services()->setValue('session', $session); _elgg_services()->session->start(); $this->handler = _elgg_services()->serveFileHandler; $file = new \ElggFile(); $file->owner_guid = 1; $file->setFilename("foobar.txt"); $this->file = $file; }
public function testMigrate() { $session = \ElggSession::getMock(); $session->start(); $session->set('foo', 5); $id = $session->getId(); $this->assertTrue($session->migrate()); $this->assertTrue($session->has('foo')); $this->assertNotEquals($id, $session->getId()); $this->assertTrue($session->has('__elgg_session')); }
public function testPropertiesReturnCorrectClassNames() { $mgr = $this->getMock('\\Elgg\\AutoloadManager', array(), array(), '', false); $sp = new \Elgg\Di\ServiceProvider($mgr); $sp->setValue('session', \ElggSession::getMock()); $svcClasses = array('accessCache' => '\\ElggStaticVariableCache', 'accessCollections' => '\\Elgg\\Database\\AccessCollections', 'actions' => '\\Elgg\\ActionsService', 'adminNotices' => '\\Elgg\\Database\\AdminNotices', 'annotations' => '\\Elgg\\Database\\Annotations', 'autoP' => '\\ElggAutoP', 'autoloadManager' => '\\Elgg\\AutoloadManager', 'config' => '\\Elgg\\Config', 'configTable' => '\\Elgg\\Database\\ConfigTable', 'context' => '\\Elgg\\Context', 'datalist' => '\\Elgg\\Database\\Datalist', 'db' => '\\Elgg\\Database', 'entityTable' => '\\Elgg\\Database\\EntityTable', 'events' => '\\Elgg\\EventsService', 'externalFiles' => '\\Elgg\\Assets\\ExternalFiles', 'hooks' => '\\Elgg\\PluginHooksService', 'input' => '\\Elgg\\Http\\Input', 'logger' => '\\Elgg\\Logger', 'metadataCache' => '\\Elgg\\Cache\\MetadataCache', 'metadataTable' => '\\Elgg\\Database\\MetadataTable', 'metastringsTable' => '\\Elgg\\Database\\MetastringsTable', 'passwords' => '\\Elgg\\PasswordService', 'plugins' => '\\Elgg\\Database\\Plugins', 'request' => '\\Elgg\\Http\\Request', 'relationshipsTable' => '\\Elgg\\Database\\RelationshipsTable', 'router' => '\\Elgg\\Router', 'session' => '\\ElggSession', 'simpleCache' => '\\Elgg\\Cache\\SimpleCache', 'siteSecret' => '\\Elgg\\Database\\SiteSecret', 'stickyForms' => '\\Elgg\\Forms\\StickyForms', 'subtypeTable' => '\\Elgg\\Database\\SubtypeTable', 'systemCache' => '\\Elgg\\Cache\\SystemCache', 'translator' => '\\Elgg\\I18n\\Translator', 'usersTable' => '\\Elgg\\Database\\UsersTable', 'views' => '\\Elgg\\ViewsService', 'widgets' => '\\Elgg\\WidgetsService'); foreach ($svcClasses as $key => $class) { $obj1 = $sp->{$key}; $obj2 = $sp->{$key}; $this->assertInstanceOf($class, $obj1); $this->assertSame($obj1, $obj2); } }
/** * Update a specific piece of metadata. * * @param int $id ID of the metadata to update * @param string $name Metadata name * @param string $value Metadata value * @param string $value_type Value type * @param int $owner_guid Owner guid * @param int $access_id Access ID * * @return bool */ function update($id, $name, $value, $value_type, $owner_guid, $access_id) { $id = (int) $id; if (!($md = $this->get($id))) { return false; } if (!$md->canEdit()) { return false; } // If memcached then we invalidate the cache for this entry static $metabyname_memcache; if (!$metabyname_memcache && is_memcache_available()) { $metabyname_memcache = new \ElggMemcache('metabyname_memcache'); } if ($metabyname_memcache) { // @todo fix memcache (name_id is not a property of \ElggMetadata) $metabyname_memcache->delete("{$md->entity_guid}:{$md->name_id}"); } $value_type = detect_extender_valuetype($value, $this->db->sanitizeString(trim($value_type))); $owner_guid = (int) $owner_guid; if ($owner_guid == 0) { $owner_guid = $this->session->getLoggedInUserGuid(); } $access_id = (int) $access_id; // Support boolean types (as integers) if (is_bool($value)) { $value = (int) $value; } $value_id = $this->metastringsTable->getId($value); if (!$value_id) { return false; } $name_id = $this->metastringsTable->getId($name); if (!$name_id) { return false; } // If ok then add it $query = "UPDATE {$this->table}" . " set name_id='{$name_id}', value_id='{$value_id}', value_type='{$value_type}', access_id={$access_id}," . " owner_guid={$owner_guid} where id={$id}"; $result = $this->db->updateData($query); if ($result !== false) { $this->cache->save($md->entity_guid, $name, $value); // @todo this event tells you the metadata has been updated, but does not // let you do anything about it. What is needed is a plugin hook before // the update that passes old and new values. $obj = $this->get($id); $this->events->trigger('update', 'metadata', $obj); } return $result; }
public function setUp() { $this->containerGuid = 42; // mock \ElggObject that has a container guid $object = $this->getMock('\\ElggObject', array('getContainerGUID'), array(), '', false); $object->expects($this->any())->method('getContainerGUID')->will($this->returnValue($this->containerGuid)); // mock event that holds the mock object $this->event = $this->getMock('\\Elgg\\Notifications\\Event', array('getObject'), array(), '', false); $this->event->expects($this->any())->method('getObject')->will($this->returnValue($object)); $this->db = $this->getMock('\\Elgg\\Database', array('getData', 'getTablePrefix', 'sanitizeString'), array(), '', false); $this->db->expects($this->any())->method('getTablePrefix')->will($this->returnValue('elgg_')); $this->db->expects($this->any())->method('sanitizeString')->will($this->returnArgument(0)); // Event class has dependency on elgg_get_logged_in_user_guid() _elgg_services()->setValue('session', \ElggSession::getMock()); }
public function testCanSetLoggedInUser() { $user = $this->getMockBuilder(\ElggUser::class)->setMethods(['__get'])->disableOriginalConstructor()->getMock(); $user->expects($this->any())->method('__get')->will($this->returnCallback(function ($name) { if ($name == 'guid') { return 123; } })); $session = \ElggSession::getMock(); $session->setLoggedInUser($user); $this->assertEquals($user, $session->getLoggedInUser()); $this->assertEquals(123, $session->getLoggedInUserGuid()); $session->removeLoggedInUser(); $this->assertNull($session->getLoggedInUser()); }
public function setUp() { $app = _elgg_testing_application(); $dataroot = _elgg_testing_config()->getDataPath(); $session = \ElggSession::getMock(); _elgg_services()->setValue('session', $session); _elgg_services()->session->start(); $site_secret_mock = $this->getMockBuilder('\\Elgg\\Database\\SiteSecret')->getMock(); $site_secret_mock->method('init')->willReturn('strongSiteSecret1234567890'); _elgg_services()->setValue('siteSecret', $site_secret_mock); $this->handler = new ServeFileHandler($app); $file_mock = $this->getMockBuilder('\\ElggFile')->disableOriginalConstructor()->getMock(); $file_mock->method('getFileNameOnFilestore')->willReturn("{$dataroot}file_service/foobar.txt"); $file_mock->method('exists')->willReturn(true); $this->file = $file_mock; }
/** * Get a variable from either the session, or if its not in the session attempt to get it from * an api call. */ function offsetGet($key) { if (!ElggSession::$__localcache) { ElggSession::$__localcache = array(); } if (isset($_SESSION[$key])) { return $_SESSION[$key]; } if (isset(ElggSession::$__localcache[$key])) { return ElggSession::$__localcache[$key]; } $value = null; $value = trigger_plugin_hook('session:get', $key, null, $value); ElggSession::$__localcache[$key] = $value; return ElggSession::$__localcache[$key]; }
protected function setUp() { _elgg_filestore_init(); $session = \ElggSession::getMock(); _elgg_services()->setValue('session', $session); _elgg_services()->session->start(); $file = new \ElggFile(); $file->owner_guid = 1; $file->setFilename("foobar.txt"); $this->file = $file; $dataroot = elgg_get_config('dataroot'); if (is_dir($dataroot . '1/2/')) { // we use this for writing new files _elgg_rmdir($dataroot . '1/2/'); } }
public function setUp() { $this->hooks = new \Elgg\PluginHooksService(); $this->queue = new \Elgg\Queue\MemoryQueue(); $dbMock = $this->getMockBuilder('\\Elgg\\Database')->disableOriginalConstructor()->getMock(); $this->sub = new \Elgg\Notifications\SubscriptionsService($dbMock); $this->translator = new \Elgg\I18n\Translator(); $this->session = \ElggSession::getMock(); // User mock that supports calling $user->isBanned() $user_123 = $this->getMockBuilder('\\ElggEntity')->disableOriginalConstructor()->getMock(); $user_123->expects($this->any())->method('isBanned')->will($this->returnValue(false)); // Database mock that returns the user_123 $this->entities = $this->getMockBuilder('\\Elgg\\Database\\EntityTable')->disableOriginalConstructor()->getMock(); $this->entities->expects($this->any())->method('get')->with($this->equalTo('123'))->will($this->returnValue($user_123)); // Event class has dependency on elgg_get_logged_in_user_guid() _elgg_services()->setValue('session', $this->session); }
/** * Save the registers to the session * * The method of displaying these messages differs depending upon plugins and * viewtypes. The core default viewtype retrieves messages in * {@link views/default/page/shells/default.php} and displays messages as * javascript popups. * * Messages are stored as strings in the Elgg session as ['msg'][$register] array. * * @param RegisterSet $set The set of registers * @return void */ public function saveRegisters(RegisterSet $set) { $filter = function ($el) { return is_string($el) && $el !== ""; }; $data = []; foreach ($set as $prop => $values) { if (!is_array($values)) { continue; } $arr = array_filter($values, $filter); if ($arr) { $data[$prop] = array_values($arr); } } $this->session->set(self::SESSION_KEY, $data); }
public function setUp() { $this->user = $this->mocks()->getUser(); $this->owner_guid = $this->user->guid; $dir = (new EntityDirLocator($this->owner_guid))->getPath(); $this->owner_dir_path = elgg_get_config('dataroot') . $dir; _elgg_services()->hooks->backup(); _elgg_services()->events->backup(); _elgg_filestore_init(); // we will need simpletype hook to work // Events service is trying to connect to the DB _elgg_services()->events->unregisterHandler('all', 'all', 'system_log_listener'); _elgg_services()->events->unregisterHandler('log', 'systemlog', 'system_log_default_logger'); $request = $this->prepareHttpRequest(); _elgg_services()->setValue('request', $request); _elgg_services()->setValue('uploads', new UploadService($request)); $session = \ElggSession::getMock(); _elgg_services()->setValue('session', $session); _elgg_services()->session->start(); }
public function setUp() { $sp = _elgg_services(); $sp->setValue('session', \ElggSession::getMock()); }
public function setUp() { $this->service = new UrlSigner(); $this->url = '/foo?a=b&c[]=1&c[]=2&c[]=0,5&_d=@username&e=%20'; _elgg_services()->setValue('session', \ElggSession::getMock()); }
protected function setUp() { // required by \ElggEntity when setting the owner/container _elgg_services()->setValue('session', \ElggSession::getMock()); }
/** * Create a user account for the admin * * @param array $submissionVars Submitted vars * @param bool $login Login in the admin user? * * @return bool */ protected function createAdminAccount($submissionVars, $login = FALSE) { try { $guid = register_user($submissionVars['username'], $submissionVars['password1'], $submissionVars['displayname'], $submissionVars['email']); } catch (Exception $e) { register_error($e->getMessage()); return false; } if (!$guid) { register_error(_elgg_services()->translator->translate('install:admin:cannot_create')); return false; } $user = get_entity($guid); if (!$user instanceof ElggUser) { register_error(_elgg_services()->translator->translate('install:error:loadadmin')); return false; } elgg_set_ignore_access(TRUE); if ($user->makeAdmin() == FALSE) { register_error(_elgg_services()->translator->translate('install:error:adminaccess')); } else { _elgg_services()->configTable->set('admin_registered', 1); } elgg_set_ignore_access(false); // add validation data to satisfy user validation plugins create_metadata($guid, 'validated', TRUE, '', 0, ACCESS_PUBLIC); create_metadata($guid, 'validated_method', 'admin_user', '', 0, ACCESS_PUBLIC); if ($login) { $handler = new Elgg\Http\DatabaseSessionHandler(_elgg_services()->db); // session.cache_limiter is unfortunately set to "" by the NativeSessionStorage constructor, // so we must capture and inject it directly. $options = ['cache_limiter' => session_cache_limiter()]; $storage = new Symfony\Component\HttpFoundation\Session\Storage\NativeSessionStorage($options, $handler); $session = new ElggSession(new Symfony\Component\HttpFoundation\Session\Session($storage)); $session->setName('Elgg'); _elgg_services()->setValue('session', $session); if (login($user) == FALSE) { register_error(_elgg_services()->translator->translate('install:error:adminlogin')); } } return TRUE; }
public function testLoggedOutUser() { $originalSession = _elgg_services()->session; _elgg_services()->setValue('session', \ElggSession::getMock()); $sql = _elgg_get_access_where_sql(); $access_clause = $this->getLoggedOutAccessListClause('e'); $ans = "(({$access_clause}) AND (e.enabled = 'yes'))"; $this->assertTrue($this->assertSqlEqual($ans, $sql), "{$sql} does not match {$ans}"); _elgg_services()->setValue('session', $originalSession); }