/**
  * Helper method for applicablePages() methods.  Acts as a skeleton implementation.
  *
  * @param array $ids The IDs passed to applicablePages
  * @param string $methodName The canXXX() method to call on each page to check if the action is applicable
  * @param bool $checkStagePages Set to true if you want to check stage pages
  * @param bool $checkLivePages Set to true if you want to check live pages (e.g, for deleted-from-draft)
  * @return array
  */
 public function applicablePagesHelper($ids, $methodName, $checkStagePages = true, $checkLivePages = true)
 {
     if (!is_array($ids)) {
         user_error("Bad \$ids passed to applicablePagesHelper()", E_USER_WARNING);
     }
     if (!is_string($methodName)) {
         user_error("Bad \$methodName passed to applicablePagesHelper()", E_USER_WARNING);
     }
     $applicableIDs = array();
     $managedClass = $this->managedClass;
     $draftPages = DataObject::get($managedClass)->byIDs($ids);
     // Filter out the live-only ids
     $onlyOnLive = array_fill_keys($ids, true);
     if ($checkStagePages) {
         foreach ($draftPages as $obj) {
             unset($onlyOnLive[$obj->ID]);
             if ($obj->{$methodName}()) {
                 $applicableIDs[] = $obj->ID;
             }
         }
     }
     $onlyOnLive = array_keys($onlyOnLive);
     if ($checkLivePages && $onlyOnLive && Object::has_extension($managedClass, 'SilverStripe\\ORM\\Versioning\\Versioned')) {
         // Get the pages that only exist on live (deleted from stage)
         $livePages = Versioned::get_by_stage($managedClass, "Live")->byIDs($onlyOnLive);
         foreach ($livePages as $obj) {
             if ($obj->{$methodName}()) {
                 $applicableIDs[] = $obj->ID;
             }
         }
     }
     return $applicableIDs;
 }
 /**
  * Find a list of classes, each of which with a list of methods to invoke
  * to lookup owners.
  *
  * @return array
  */
 protected function lookupReverseOwners()
 {
     // Find all classes with 'owns' config
     $lookup = array();
     foreach (ClassInfo::subclassesFor('SilverStripe\\ORM\\DataObject') as $class) {
         // Ensure this class is versioned
         if (!Object::has_extension($class, static::class)) {
             continue;
         }
         // Check owned objects for this class
         $owns = Config::inst()->get($class, 'owns', Config::UNINHERITED);
         if (empty($owns)) {
             continue;
         }
         $instance = DataObject::singleton($class);
         foreach ($owns as $owned) {
             // Find owned class
             $ownedClass = $instance->getRelationClass($owned);
             // Skip custom methods that don't have db relationsm
             if (!$ownedClass) {
                 continue;
             }
             if ($ownedClass === DataObject::class) {
                 throw new LogicException(sprintf("Relation %s on class %s cannot be owned as it is polymorphic", $owned, $class));
             }
             // Add lookup for owned class
             if (!isset($lookup[$ownedClass])) {
                 $lookup[$ownedClass] = array();
             }
             $lookup[$ownedClass][] = ['class' => $class, 'relation' => $owned];
         }
     }
     return $lookup;
 }
 /**
  * Safely get a DataObject from a client-supplied ID and ClassName, checking: argument
  * validity; existence; and canView permissions.
  *
  * @param int $id The ID of the DataObject
  * @param string $class The Class of the DataObject
  * @return DataObject The referenced DataObject
  * @throws HTTPResponse_Exception
  */
 protected function getObject($id, $class)
 {
     $id = (int) $id;
     $class = ClassInfo::class_name($class);
     if (!$class || !is_subclass_of($class, 'SilverStripe\\ORM\\DataObject') || !Object::has_extension($class, 'SilverStripe\\ORM\\Versioning\\Versioned')) {
         $this->controller->httpError(400, _t('AddToCampaign.ErrorGeneral', 'We apologise, but there was an error'));
         return null;
     }
     $object = DataObject::get($class)->byID($id);
     if (!$object) {
         $this->controller->httpError(404, _t('AddToCampaign.ErrorNotFound', 'That {Type} couldn\'t be found', '', ['Type' => $class]));
         return null;
     }
     if (!$object->canView()) {
         $this->controller->httpError(403, _t('AddToCampaign.ErrorItemPermissionDenied', 'It seems you don\'t have the necessary permissions to add {ObjectTitle} to a campaign', '', ['ObjectTitle' => $object->Title]));
         return null;
     }
     return $object;
 }
 public function testRemoveExtensionWithParameters()
 {
     ObjectTest_ExtensionRemoveTest::add_extension('ObjectTest_ExtendTest2("MyParam")');
     $this->assertTrue(ObjectTest_ExtensionRemoveTest::has_extension('ObjectTest_ExtendTest2'), "Extension added through \$add_extension() are added correctly");
     ObjectTest_ExtensionRemoveTest::remove_extension('ObjectTest_ExtendTest2');
     $this->assertFalse(Object::has_extension('ObjectTest_ExtensionRemoveTest', 'ObjectTest_ExtendTest2'), "Extension added through \$add_extension() are detected as removed in has_extension()");
     $objectTest_ExtensionRemoveTest = new ObjectTest_ExtensionRemoveTest();
     $this->assertFalse($objectTest_ExtensionRemoveTest->hasExtension('ObjectTest_ExtendTest2'), "Extensions added through \$extensions are detected as removed in instances through hasExtension()");
 }