protected function createCallableArray(&$extraArray, $interfaceToQuery, $variableMethod, $createObject = false)
 {
     $implementers = ClassInfo::implementorsOf($interfaceToQuery);
     if ($implementers) {
         foreach ($implementers as $implementer) {
             // Create a new instance of the object for method calls
             if ($createObject) {
                 $implementer = new $implementer();
             }
             // Get the exposed variables
             $exposedVariables = call_user_func(array($implementer, $variableMethod));
             foreach ($exposedVariables as $varName => $details) {
                 if (!is_array($details)) {
                     $details = array('method' => $details, 'casting' => Config::inst()->get('SilverStripe\\View\\ViewableData', 'default_cast', Config::FIRST_SET));
                 }
                 // If just a value (and not a key => value pair), use it for both key and value
                 if (is_numeric($varName)) {
                     $varName = $details['method'];
                 }
                 // Add in a reference to the implementing class (might be a string class name or an instance)
                 $details['implementer'] = $implementer;
                 // And a callable array
                 if (isset($details['method'])) {
                     $details['callable'] = array($implementer, $details['method']);
                 }
                 // Save with both uppercase & lowercase first letter, so either works
                 $lcFirst = strtolower($varName[0]) . substr($varName, 1);
                 $extraArray[$lcFirst] = $details;
                 $extraArray[ucfirst($varName)] = $details;
             }
         }
     }
 }
 /**
  * @inheritdoc
  *
  * @param HTTPRequest $request
  * @param Session $session
  * @param DataModel $model
  *
  * @return bool
  */
 public function preRequest(HTTPRequest $request, Session $session, DataModel $model)
 {
     if (array_key_exists('flush', $request->getVars())) {
         foreach (ClassInfo::implementorsOf('SilverStripe\\Core\\Flushable') as $class) {
             $class::flush();
         }
     }
     return true;
 }
 public function testClassInfoIsCorrect()
 {
     $this->assertContains('SilverStripe\\Framework\\Tests\\ClassI', ClassInfo::implementorsOf('SilverStripe\\Security\\PermissionProvider'));
     //because we're using a nested manifest we have to "coalesce" the descendants again to correctly populate the
     // descendants of the core classes we want to test against - this is a limitation of the test manifest not
     // including all core classes
     $method = new ReflectionMethod($this->manifest, 'coalesceDescendants');
     $method->setAccessible(true);
     $method->invoke($this->manifest, 'SilverStripe\\Admin\\ModelAdmin');
     $this->assertContains('SilverStripe\\Framework\\Tests\\ClassI', ClassInfo::subclassesFor('SilverStripe\\Admin\\ModelAdmin'));
 }
 /**
  * Get a list of all available permission codes, both defined through the
  * {@link PermissionProvider} interface, and all not explicitly defined codes existing
  * as a {@link Permission} database record. By default, the results are
  * grouped as denoted by {@link Permission_Group}.
  *
  * @param bool $grouped Group results into an array of permission groups.
  * @return array Returns an array of all available permission codes. The
  *  array indicies are the permission codes as used in
  *  {@link Permission::check()}. The value is a description
  *  suitable for using in an interface.
  */
 public static function get_codes($grouped = true)
 {
     $classes = ClassInfo::implementorsOf('SilverStripe\\Security\\PermissionProvider');
     $allCodes = array();
     $adminCategory = _t('Permission.AdminGroup', 'Administrator');
     $allCodes[$adminCategory]['ADMIN'] = array('name' => _t('Permission.FULLADMINRIGHTS', 'Full administrative rights'), 'help' => _t('Permission.FULLADMINRIGHTS_HELP', 'Implies and overrules all other assigned permissions.'), 'sort' => 100000);
     if ($classes) {
         foreach ($classes as $class) {
             $SNG = singleton($class);
             if ($SNG instanceof TestOnly) {
                 continue;
             }
             $someCodes = $SNG->providePermissions();
             if ($someCodes) {
                 foreach ($someCodes as $k => $v) {
                     if (is_array($v)) {
                         // There must be a category and name key.
                         if (!isset($v['category'])) {
                             user_error("The permission {$k} must have a category key", E_USER_WARNING);
                         }
                         if (!isset($v['name'])) {
                             user_error("The permission {$k} must have a name key", E_USER_WARNING);
                         }
                         if (!isset($allCodes[$v['category']])) {
                             $allCodes[$v['category']] = array();
                         }
                         $allCodes[$v['category']][$k] = array('name' => $v['name'], 'help' => isset($v['help']) ? $v['help'] : null, 'sort' => isset($v['sort']) ? $v['sort'] : 0);
                     } else {
                         $allCodes['Other'][$k] = array('name' => $v, 'help' => null, 'sort' => 0);
                     }
                 }
             }
         }
     }
     $flatCodeArray = array();
     foreach ($allCodes as $category) {
         foreach ($category as $code => $permission) {
             $flatCodeArray[] = $code;
         }
     }
     $otherPerms = DB::query("SELECT DISTINCT \"Code\" From \"Permission\" WHERE \"Code\" != ''")->column();
     if ($otherPerms) {
         foreach ($otherPerms as $otherPerm) {
             if (!in_array($otherPerm, $flatCodeArray)) {
                 $allCodes['Other'][$otherPerm] = array('name' => $otherPerm, 'help' => null, 'sort' => 0);
             }
         }
     }
     // Don't let people hijack ADMIN rights
     if (!Permission::check("ADMIN")) {
         unset($allCodes['ADMIN']);
     }
     ksort($allCodes);
     $returnCodes = array();
     foreach ($allCodes as $category => $permissions) {
         if ($grouped) {
             uasort($permissions, array(__CLASS__, 'sort_permissions'));
             $returnCodes[$category] = $permissions;
         } else {
             $returnCodes = array_merge($returnCodes, $permissions);
         }
     }
     return $returnCodes;
 }