/**
  * Returns a readonly span containing the correct value.
  *
  * @param array $properties
  *
  * @return string
  */
 public function Field($properties = array())
 {
     $source = ArrayLib::flatten($this->getSource());
     $values = $this->getValueArray();
     // Get selected values
     $mapped = array();
     foreach ($values as $value) {
         if (isset($source[$value])) {
             $mapped[] = $source[$value];
         }
     }
     // Don't check if string arguments are matching against the source,
     // as they might be generated HTML diff views instead of the actual values
     if ($this->value && is_string($this->value) && empty($mapped)) {
         $mapped = array(trim($this->value));
         $values = array();
     }
     if ($mapped) {
         $attrValue = implode(', ', array_values($mapped));
         if (!$this->dontEscape) {
             $attrValue = Convert::raw2xml($attrValue);
         }
         $inputValue = implode(', ', array_values($values));
     } else {
         $attrValue = '<i>(' . _t('FormField.NONE', 'none') . ')</i>';
         $inputValue = '';
     }
     $properties = array_merge($properties, array('AttrValue' => $attrValue, 'InputValue' => $inputValue));
     return parent::Field($properties);
 }
 public function getSearchContext()
 {
     $context = parent::getSearchContext();
     $categories = EmailTemplate::get()->column('Category');
     $context->getFields()->replaceField('q[Category]', new DropdownField('q[Category]', 'Category', ArrayLib::valuekey($categories)));
     return $context;
 }
	/**
	 * Create a new DataObjectSet. If you pass one or more arguments, it will try to convert them into {@link ArrayData} objects. 
	 * @todo Does NOT automatically convert objects with complex datatypes (e.g. converting arrays within an objects to its own DataObjectSet)							
	 * 
	 * @param ViewableData|array|mixed $items Parameters to use in this set, either as an associative array, object with simple properties, or as multiple parameters.
	 */
	public function __construct($items = null) {
		if($items) {
			// if the first parameter is not an array, or we have more than one parameter, collate all parameters to an array
			// otherwise use the passed array
			$itemsArr = (!is_array($items) || count(func_get_args()) > 1) ? func_get_args() : $items;
			
			// We now have support for using the key of a data object set
			foreach($itemsArr as $i => $item) {
				if(is_subclass_of($item, 'ViewableData')) {
					$this->items[$i] = $item;
				} elseif(is_object($item) || ArrayLib::is_associative($item)) {
					$this->items[$i] = new ArrayData($item);
				} else {
					user_error(
						"DataObjectSet::__construct: Passed item #{$i} is not an object or associative array, 
						can't be properly iterated on in templates", 
						E_USER_WARNING
					);						
					$this->items[$i] = $item;
				}
			}

			
		}
		parent::__construct();
	}
 /**
  * Get a value from a given field
  *
  * @param string $f field key
  * @return mixed
  */
 public function getField($f)
 {
     if (is_object($this->array[$f]) && !$this->array[$f] instanceof ViewableData || is_array($this->array[$f]) && ArrayLib::is_associative($this->array[$f])) {
         return new ArrayData($this->array[$f]);
     }
     return $this->array[$f];
 }
Exemple #5
0
	/**
	 * @deprecated 3.0
	 */
	public function __construct($items = array()) {
		Deprecation::notice('3.0', 'Use DataList or ArrayList instead');

		if ($items) {
			if (!is_array($items) || func_num_args() > 1) {
				$items = func_get_args();
			}

			foreach ($items as $i => $item) {
				if ($item instanceof ViewableData) {
					continue;
				}

				if (is_object($item) || ArrayLib::is_associative($item)) {
					$items[$i] = new ArrayData($item);
				} else {
					user_error(
						"DataObjectSet::__construct: Passed item #{$i} is not an"
						. ' and object or associative array, can\'t be properly'
						. ' iterated on in templates', E_USER_WARNING
					);
				}
			}
		}

		parent::__construct($items);
	}
 /**
  * Add a mapping of nice short permalinks to a full long path
  *
  * <code>
  * DocumentationPermalinks::add(array(
  * 	'debugging' => 'current/en/sapphire/topics/debugging'
  * ));
  * </code>
  *
  * Do not need to include the language or the version current as it 
  * will add it based off the language or version in the session
  *
  * @param array
  */
 public static function add($map = array())
 {
     if (ArrayLib::is_associative($map)) {
         self::$mapping = array_merge(self::$mapping, $map);
     } else {
         user_error("DocumentationPermalinks::add() requires an associative array", E_USER_ERROR);
     }
 }
 /**
  * @covers ClassInfo::ancestry()
  */
 public function testAncestry()
 {
     $ancestry = ClassInfo::ancestry('ClassInfoTest_ChildClass');
     $expect = ArrayLib::valuekey(array('Object', 'ViewableData', 'DataObject', 'ClassInfoTest_BaseClass', 'ClassInfoTest_ChildClass'));
     $this->assertEquals($expect, $ancestry);
     $ancestry = ClassInfo::ancestry('ClassInfoTest_ChildClass', true);
     $this->assertEquals(array('ClassInfoTest_BaseClass' => 'ClassInfoTest_BaseClass'), $ancestry, '$tablesOnly option excludes memory-only inheritance classes');
 }
 public function getCMSFields()
 {
     $fields = FieldList::create(TabSet::create('Root'));
     $fields->addFieldsToTab('Root.Main', array(TextField::create('Title'), TextareaField::create('Description'), CurrencyField::create('PricePerNight', 'Price (per night)'), DropdownField::create('Bedrooms')->setSource(ArrayLib::valuekey(range(1, 10))), DropdownField::create('Bathrooms')->setSource(ArrayLib::valuekey(range(1, 10))), DropdownField::create('RegionID', 'Region')->setSource(Region::get()->map('ID', 'Title'))->setEmptyString('-- Select a region --'), CheckboxField::create('FeaturedOnHomepage', 'Feature on homepage')));
     $fields->addFieldToTab('Root.Photos', $upload = UploadField::create('PrimaryPhoto', 'Primary photo'));
     $upload->getValidator()->setAllowedExtensions(array('png', 'jpeg', 'jpg', 'gif'));
     $upload->setFolderName('property-photos');
     return $fields;
 }
 public function testFlatten()
 {
     $options = array('1' => 'one', '2' => 'two');
     $expected = $options;
     $this->assertEquals($expected, ArrayLib::flatten($options));
     $options = array('1' => array('2' => 'two', '3' => 'three'), '4' => 'four');
     $expected = array('2' => 'two', '3' => 'three', '4' => 'four');
     $this->assertEquals($expected, ArrayLib::flatten($options));
 }
 protected function generateColorPalette($fieldName, $paletteSetting)
 {
     $palette = $this->owner->config()->get($paletteSetting) ? $this->owner->config()->get($paletteSetting) : Config::inst()->get($this->class, $paletteSetting);
     $field = ColorPaletteField::create($fieldName, $this->owner->fieldLabel($fieldName), ArrayLib::valuekey($palette));
     if (Config::inst()->get($this->class, 'colors_can_be_empty')) {
         $field = $field->setEmptyString('none');
     }
     return $field;
 }
 /**
  * Process the given URL, creating the appropriate controller and executing it.
  * 
  * Request processing is handled as follows:
  *  - Director::direct() creates a new SS_HTTPResponse object and passes this to Director::handleRequest().
  *  - Director::handleRequest($request) checks each of the Director rules and identifies a controller to handle this 
  *    request.
  *  - Controller::handleRequest($request) is then called.  This will find a rule to handle the URL, and call the rule
  *    handling method.
  *  - RequestHandler::handleRequest($request) is recursively called whenever a rule handling method returns a
  *    RequestHandler object.
  *
  * In addition to request processing, Director will manage the session, and perform the output of the actual response
  * to the browser.
  * 
  * @param $url String, the URL the user is visiting, without the querystring.
  * @uses handleRequest() rule-lookup logic is handled by this.
  * @uses Controller::run() Controller::run() handles the page logic for a Director::direct() call.
  */
 static function direct($url)
 {
     // Validate $_FILES array before merging it with $_POST
     foreach ($_FILES as $k => $v) {
         if (is_array($v['tmp_name'])) {
             $v = ArrayLib::array_values_recursive($v['tmp_name']);
             foreach ($v as $tmpFile) {
                 if ($tmpFile && !is_uploaded_file($tmpFile)) {
                     user_error("File upload '{$k}' doesn't appear to be a valid upload", E_USER_ERROR);
                 }
             }
         } else {
             if ($v['tmp_name'] && !is_uploaded_file($v['tmp_name'])) {
                 user_error("File upload '{$k}' doesn't appear to be a valid upload", E_USER_ERROR);
             }
         }
     }
     $req = new SS_HTTPRequest(isset($_SERVER['X-HTTP-Method-Override']) ? $_SERVER['X-HTTP-Method-Override'] : $_SERVER['REQUEST_METHOD'], $url, $_GET, array_merge((array) $_POST, (array) $_FILES), @file_get_contents('php://input'));
     // @todo find better way to extract HTTP headers
     if (isset($_SERVER['HTTP_ACCEPT'])) {
         $req->addHeader("Accept", $_SERVER['HTTP_ACCEPT']);
     }
     if (isset($_SERVER['CONTENT_TYPE'])) {
         $req->addHeader("Content-Type", $_SERVER['CONTENT_TYPE']);
     }
     if (isset($_SERVER['HTTP_REFERER'])) {
         $req->addHeader("Referer", $_SERVER['HTTP_REFERER']);
     }
     // Load the session into the controller
     $session = new Session(isset($_SESSION) ? $_SESSION : null);
     $result = Director::handleRequest($req, $session);
     $session->inst_save();
     // Return code for a redirection request
     if (is_string($result) && substr($result, 0, 9) == 'redirect:') {
         $response = new SS_HTTPResponse();
         $response->redirect(substr($result, 9));
         $response->output();
         // Handle a controller
     } else {
         if ($result) {
             if ($result instanceof SS_HTTPResponse) {
                 $response = $result;
             } else {
                 $response = new SS_HTTPResponse();
                 $response->setBody($result);
             }
             // ?debug_memory=1 will output the number of bytes of memory used for this request
             if (isset($_REQUEST['debug_memory']) && $_REQUEST['debug_memory']) {
                 Debug::message(sprintf("Peak memory usage in bytes: %s", number_format(memory_get_peak_usage(), 0)));
             } else {
                 $response->output();
             }
             //$controllerObj->getSession()->inst_save();
         }
     }
 }
Exemple #12
0
 /**
  * Process the given URL, creating the appropriate controller and executing it.
  * 
  * Request processing is handled as follows:
  *  - Director::direct() creates a new SS_HTTPResponse object and passes this to Director::handleRequest().
  *  - Director::handleRequest($request) checks each of the Director rules and identifies a controller to handle this 
  *    request.
  *  - Controller::handleRequest($request) is then called.  This will find a rule to handle the URL, and call the rule
  *    handling method.
  *  - RequestHandler::handleRequest($request) is recursively called whenever a rule handling method returns a
  *    RequestHandler object.
  *
  * In addition to request processing, Director will manage the session, and perform the output of the actual response
  * to the browser.
  * 
  * @param $url String, the URL the user is visiting, without the querystring.
  * @uses handleRequest() rule-lookup logic is handled by this.
  * @uses Controller::run() Controller::run() handles the page logic for a Director::direct() call.
  */
 static function direct($url, DataModel $model)
 {
     // Validate $_FILES array before merging it with $_POST
     foreach ($_FILES as $k => $v) {
         if (is_array($v['tmp_name'])) {
             $v = ArrayLib::array_values_recursive($v['tmp_name']);
             foreach ($v as $tmpFile) {
                 if ($tmpFile && !is_uploaded_file($tmpFile)) {
                     user_error("File upload '{$k}' doesn't appear to be a valid upload", E_USER_ERROR);
                 }
             }
         } else {
             if ($v['tmp_name'] && !is_uploaded_file($v['tmp_name'])) {
                 user_error("File upload '{$k}' doesn't appear to be a valid upload", E_USER_ERROR);
             }
         }
     }
     $req = new SS_HTTPRequest(isset($_SERVER['X-HTTP-Method-Override']) ? $_SERVER['X-HTTP-Method-Override'] : $_SERVER['REQUEST_METHOD'], $url, $_GET, array_merge((array) $_POST, (array) $_FILES), @file_get_contents('php://input'));
     // Load the request headers. If we're not running on Apache, then we
     // need to manually extract the headers from the $_SERVER array.
     if (function_exists('apache_request_headers')) {
         $headers = apache_request_headers();
     } else {
         $headers = self::extract_request_headers($_SERVER);
     }
     foreach ($headers as $header => $value) {
         $req->addHeader($header, $value);
     }
     // Load the session into the controller
     $session = new Session(isset($_SESSION) ? $_SESSION : null);
     $result = Director::handleRequest($req, $session, $model);
     $session->inst_save();
     // Return code for a redirection request
     if (is_string($result) && substr($result, 0, 9) == 'redirect:') {
         $response = new SS_HTTPResponse();
         $response->redirect(substr($result, 9));
         $response->output();
         // Handle a controller
     } else {
         if ($result) {
             if ($result instanceof SS_HTTPResponse) {
                 $response = $result;
             } else {
                 $response = new SS_HTTPResponse();
                 $response->setBody($result);
             }
             // ?debug_memory=1 will output the number of bytes of memory used for this request
             if (isset($_REQUEST['debug_memory']) && $_REQUEST['debug_memory']) {
                 Debug::message(sprintf("Peak memory usage in bytes: %s", number_format(memory_get_peak_usage(), 0)));
             } else {
                 $response->output();
             }
             //$controllerObj->getSession()->inst_save();
         }
     }
 }
Exemple #13
0
 /**
  * @param string $name - Name of field
  * @return FormField
  */
 protected function FieldCurrency($name)
 {
     $allowedCurrencies = $this->getAllowedCurrencies();
     if ($allowedCurrencies) {
         $field = new DropdownField("{$name}[Currency]", _t('MoneyField.FIELDLABELCURRENCY', 'Currency'), ArrayLib::is_associative($allowedCurrencies) ? $allowedCurrencies : array_combine($allowedCurrencies, $allowedCurrencies));
     } else {
         $field = new TextField("{$name}[Currency]", _t('MoneyField.FIELDLABELCURRENCY', 'Currency'));
     }
     return $field;
 }
 /**
  * Update the SearchForm to use dropdown fields for MessageType/Status filters
  * @return Form
  **/
 public function SearchForm()
 {
     $form = parent::SearchForm();
     $fields = $form->Fields();
     $q = $this->getRequest()->requestVar('q');
     $fields->removeByName('q[MessageType]');
     $fields->push(DropdownField::create('q[MessageType]', 'Message Type', ArrayLib::valuekey(Config::inst()->get('TimedNotice', 'message_types')), isset($q['MessageType']) ? $q['MessageType'] : null)->setEmptyString(' '));
     $fields->push(DropdownField::create('q[Status]', 'Status', ArrayLib::valuekey(Config::inst()->get('TimedNotice', 'status_options')), isset($q['Status']) ? $q['Status'] : null)->setEmptyString(' '));
     return $form;
 }
Exemple #15
0
 function testRefusesToWrapAnIndexedArray()
 {
     $array = array(0 => "One", 1 => "Two");
     $this->assertFalse(ArrayLib::is_associative($array));
     /*
      * Expect user_error() to be called below, if enabled
      * (tobych) That should be an exception. Something like:
      * $this->setExpectedException('InvalidArgumentException');
      */
     // $arrayData = new ArrayData($array);
 }
Exemple #16
0
 /**
  * @param object|array $array Either an object with simple properties or an associative array.
  * Converts object-properties to indices of an associative array.
  */
 public function __construct($array)
 {
     if (is_object($array)) {
         $this->array = self::object_to_array($array);
     } elseif (is_array($array) && ArrayLib::is_associative($array)) {
         $this->array = $array;
     } else {
         $this->array = $array;
         user_error("ArrayData::__construct: Parameter needs to be an object or associative array", E_USER_WARNING);
     }
 }
 /**
  * Gets a field from this object.
  *
  * @param string $field
  *
  * If the value is an object but not an instance of
  * ViewableData, it will be converted recursively to an
  * ArrayData.
  *
  * If the value is an associative array, it will likewise be
  * converted recursively to an ArrayData.
  */
 public function getField($f)
 {
     $value = $this->array[$f];
     if (is_object($value) && !$value instanceof ViewableData) {
         return new ArrayData($value);
     } elseif (ArrayLib::is_associative($value)) {
         return new ArrayData($value);
     } else {
         return $value;
     }
 }
 public function updateCMSFields(FieldList $fields)
 {
     // if there are Models set in the Product Category then use a dropdown to select
     if ($this->owner->Parent && $this->owner->Parent->ProductModels()->count()) {
         $fields->replaceField('Model', DropdownField::create('Model', _t("Product.MODELREQUIRED", "Model (required)"), ArrayLib::valuekey($this->owner->Parent->ProductModels()->column('Title')))->setEmptyString(_t("Product.MODELSELECT", "Select..."))->setAttribute('Required', true));
     } else {
         // Update Model for extended length
         // see config.yml for updated db settings
         $model = $fields->dataFieldByName('Model');
         $model->setMaxLength(100);
     }
 }
 public function getCMSFields()
 {
     $fields = parent::getCMSFields();
     $fields->addFieldToTab('Root.Main', TreeDropdownField::create('SourceFolderID', 'Source folder', 'Folder'), 'Content');
     $fields->addFieldToTab('Root.Main', NumericField::create('ItemsPerPage', 'Items per page'), 'Content');
     $fileFields = singleton('File')->inheritedDatabaseFields();
     $fileFields = array_merge($fileFields, array('Created' => null, 'LastEdited' => null));
     $fileFields = ArrayLib::valuekey(array_keys($fileFields));
     $fields->addFieldToTab('Root.Main', DropdownField::create('FileSortBy', 'Sort files by', $fileFields), 'Content');
     $fields->addFieldToTab('Root.Main', DropdownField::create('FileSortDir', 'Sort direction', self::$sort_dirs_map), 'Content');
     return $fields;
 }
 /**
  * Builds a new currency field based on the allowed currencies configured
  *
  * @return FormField
  */
 protected function buildCurrencyField()
 {
     $name = $this->getName();
     $allowedCurrencies = $this->getAllowedCurrencies();
     if ($allowedCurrencies) {
         $field = new DropdownField("{$name}[Currency]", _t('MoneyField.FIELDLABELCURRENCY', 'Currency'), ArrayLib::is_associative($allowedCurrencies) ? $allowedCurrencies : array_combine($allowedCurrencies, $allowedCurrencies));
     } else {
         $field = new TextField("{$name}[Currency]", _t('MoneyField.FIELDLABELCURRENCY', 'Currency'));
     }
     $field->setReadonly($this->isReadonly());
     $field->setDisabled($this->isDisabled());
     return $field;
 }
 /**
  * Returns a sorted array suitable for a dropdown with pagetypes and their translated name.
  *
  * @return array
  */
 protected function pageTypeOptions()
 {
     $pageTypes = array();
     $classes = ArrayLib::valueKey(SiteTree::page_type_classes());
     unset($classes['VirtualPage']);
     unset($classes['ErrorPage']);
     unset($classes['RedirectorPage']);
     foreach ($classes as $pageTypeClass) {
         $pageTypes[$pageTypeClass] = singleton($pageTypeClass)->i18n_singular_name();
     }
     asort($pageTypes);
     return $pageTypes;
 }
 public function PropertySearchForm()
 {
     $nights = array();
     foreach (range(1, 14) as $i) {
         $nights[$i] = "{$i} night" . ($i > 1 ? 's' : '');
     }
     $prices = array();
     foreach (range(100, 1000, 50) as $i) {
         $prices[$i] = '$' . $i;
     }
     $form = Form::create($this, 'PropertySearchForm', FieldList::create(TextField::create('Keywords')->setAttribute('placeholder', 'City, State, Country, etc...')->addExtraClass('form-control'), TextField::create('ArrivalDate', 'Arrive on...')->setAttribute('data-datepicker', true)->setAttribute('data-date-format', 'DD-MM-YYYY')->addExtraClass('form-control'), DropdownField::create('Nights', 'Stay for...')->setSource($nights)->addExtraClass('form-control'), DropdownField::create('Bedrooms')->setSource(ArrayLib::valuekey(range(1, 5)))->addExtraClass('form-control'), DropdownField::create('Bathrooms')->setSource(ArrayLib::valuekey(range(1, 5)))->addExtraClass('form-control'), DropdownField::create('MinPrice', 'Min. price')->setEmptyString('-- any --')->setSource($prices)->addExtraClass('form-control'), DropdownField::create('MaxPrice', 'Max. price')->setEmptyString('-- any --')->setSource($prices)->addExtraClass('form-control')), FieldList::create(FormAction::create('doPropertySearch', 'Search')->addExtraClass('btn-lg btn-fullcolor')));
     $form->setFormMethod('GET')->setFormAction($this->Link())->disableSecurityToken()->loadDataFrom($this->request->getVars());
     return $form;
 }
    /**
     * @return FieldSet
     */
    public function getCMSFields()
    {
        Requirements::javascript(THIRDPARTY_DIR . '/jquery/jquery.js');
        Requirements::javascript('inlinehelp/javascript/InlineHelpAdmin.js');
        return new FieldList(new TabSet('Root', new Tab('Main', new HeaderField('HelpHeader', 'Help Topic'), new TextField('Title', 'Title'), new OptionSetField('DisplayType', 'Display type', array('Tooltip' => 'Display help text and/or link in tooltip', 'Link' => 'Click the icon to go to the help link')), new HtmlEditorField('Text', 'Short help text'), new TextField('Link', 'Help link')), new Tab('Subject', new HeaderField('SubjectHeader', 'Help Subject(s)'), new TextField('DOMPattern', 'DOM pattern'), new LiteralField('DOMPatternNote', '<p>This is a jQuery (CSS)
				selector which specifies which elements to attach this help
				topic to. The same topic can be attached to multiple elements.
				</p>'), new DropdownField('DOMMethod', 'DOM attachment method', self::$attachment_method_map)), new Tab('AttachTo', new HeaderField('AttachToHeader', 'Attach Help To'), new OptionSetField('AttachType', '', array('All' => 'All pages', 'Pages' => 'Specific pages', 'Children' => 'Children of the selected page', 'Type' => 'Instances of a specific page type')), new TreeMultiSelectField('Pages', 'Pages', 'SiteTree'), new TreeDropdownField('ParentFilterID', 'Parent page', 'SiteTree'), new DropdownField('AttachPageType', 'Page type', ArrayLib::valuekey(ClassInfo::subclassesFor('Page')))), new Tab('Advanced', new HeaderField('AdvancedHeader', 'Advanced Inline Help Options'), new DropdownField('ShowTooltip', 'Show tooltip on', array('Hover' => 'On mouse hover', 'Click' => 'On mouse click')), new TextField('IconHTML', 'Icon HTML code'), new FieldGroup('Help icon position (relative to subject)', new TextField('IconMy', 'my'), new TextField('IconAt', 'at')), new FieldGroup('Help icon offset (relative to position)', new TextField('IconOffset', ''), new LiteralField('IconOffsetNote', 'format "horizontal vertical" (e.g. "15 -5")')), new FieldGroup('Tooltip position (relative to icon)', new TextField('TooltipMy', 'my'), new TextField('TooltipAt', 'at')), new LiteralField('HelpPositionNote', '<p>These allow you to
				specify the position of the elements relative to each other.
				Each position is in the format "horizontal vertical", where
				horizontal can be one of left, center or right (default
				center), and vertical can be top, center or bottom (default
				center)</p>'), new FieldGroup('Tooltip size', new TextField('TooltipWidth', ''), new LiteralField('SizeSeparator', 'x'), new TextField('TooltipHeight', ''), new LiteralField('DefaultSizeNote', '(default: 300 x "auto")')))));
    }
 /**
  * @param string $name
  * @param string $title
  * @param DataObjectInterface $object
  * @param string $sort
  * @param SS_List $source
  * @param string $titleField
  */
 public function __construct($name, $title, DataObjectInterface $object, $sort = false, SS_List $source = null, $titleField = 'Title')
 {
     $this->setSort($sort);
     if ($object->many_many($name)) {
         $dataSource = $object->{$name}();
         // Check if we're dealing with an UnsavedRelationList
         $unsaved = $dataSource instanceof UnsavedRelationList;
         // Store the relation's class name
         $class = $dataSource->dataClass();
         $this->dataClass = $class;
         // Sort the items
         if ($this->getSort()) {
             $dataSource = $dataSource->sort($this->getSort());
         }
         // If we're dealing with an UnsavedRelationList, it'll be empty, so we
         // can skip this and just use an array of all available items
         if ($unsaved) {
             $dataSource = $class::get()->map()->toArray();
         } else {
             // If we've been given a list source, filter on those IDs only.
             if ($source) {
                 $dataSource = $dataSource->filter('ID', $source->column('ID'));
             }
             // Start building the data source from scratch. Currently selected items first,
             // in the correct sort order
             $dataSource = $dataSource->map('ID', $titleField)->toArray();
             // Get the other items
             $theRest = $class::get();
             // Exclude items that we've already found
             if (!empty($dataSource)) {
                 $theRest = $theRest->exclude('ID', array_keys($dataSource));
             }
             // If we've been given a list source, filter on those IDs only
             if ($source) {
                 $theRest = $theRest->filter('ID', $source->column('ID'));
             }
             $theRest = $theRest->map('ID', $titleField)->toArray();
             // ... we then add the remaining items in whatever order they come
             $dataSource = $dataSource + $theRest;
         }
     } elseif ($source instanceof SS_List) {
         $dataSource = $source->map('ID', $titleField)->toArray();
     } elseif (is_array($source) && ArrayLib::is_associative($source)) {
         $dataSource = $source;
     } else {
         user_error('MultiSelectField::__construct(): MultiSelectField only supports many-to-many relations');
     }
     parent::__construct($name, $title, $dataSource, '', null, true);
 }
 /**
  * @return FieldSet
  */
 public function getCmsExtraFields($time)
 {
     switch ($this->Type) {
         case 'Single':
             $quantity = new ReadonlyField('OneAvailable', 'Quantity', '(One available)');
             break;
         case 'Limited':
             $quantity = new DropdownField('BookingQuantity', 'Quantity', ArrayLib::valuekey(range(1, $this->getAvailableForEvent($time))), null, null, true);
             break;
         case 'Unlimited':
             $quantity = new NumericField('BookingQuantity', 'Quantity');
             break;
     }
     return new FieldSet(new ReadonlyField('Title', 'Resource title', $this->Title), $quantity);
 }
 /**
  * Returns a readonly span containing the correct value.
  *
  * @param array $properties
  *
  * @return string
  */
 public function Field($properties = array())
 {
     $source = $this->getSource();
     // Normalize value to array to simplify further processing
     if (is_array($this->value) || is_object($this->value)) {
         $values = $this->value;
     } else {
         $values = array(trim($this->value));
     }
     $mapped = array();
     if ($source instanceof SQLMap) {
         foreach ($values as $value) {
             $mapped[] = $source->getItem($value);
         }
     } else {
         if ($source instanceof ArrayAccess || is_array($source)) {
             $source = ArrayLib::flatten($source);
             foreach ($values as $value) {
                 if (isset($source[$value])) {
                     $mapped[] = $source[$value];
                 }
             }
         } else {
             $mapped = array();
         }
     }
     // Don't check if string arguments are matching against the source,
     // as they might be generated HTML diff views instead of the actual values
     if ($this->value && !is_array($this->value) && !$mapped) {
         $mapped = array(trim($this->value));
         $values = array();
     }
     if ($mapped) {
         $attrValue = implode(', ', array_values($mapped));
         if (!$this->dontEscape) {
             $attrValue = Convert::raw2xml($attrValue);
         }
         $inputValue = implode(', ', array_values($values));
     } else {
         $attrValue = "<i>(none)</i>";
         $inputValue = '';
     }
     $properties = array_merge($properties, array('AttrValue' => $attrValue, 'InputValue' => $inputValue));
     return parent::Field($properties);
 }
 /**
  * Returns a readonly span containing the correct value.
  *
  * @param array $properties
  *
  * @return string
  */
 public function Field($properties = array())
 {
     $source = $this->getSource();
     // Normalize value to array to simplify further processing
     if (is_array($this->value) || is_object($this->value)) {
         $values = $this->value;
     } else {
         $values = array(trim($this->value));
     }
     $mapped = array();
     if ($source instanceof SQLMap) {
         foreach ($values as $value) {
             $mapped[] = $source->getItem($value);
         }
     } else {
         if ($source instanceof ArrayAccess || is_array($source)) {
             $source = ArrayLib::flatten($source);
             foreach ($values as $value) {
                 if (isset($source[$value])) {
                     $mapped[] = $source[$value];
                 }
             }
         } else {
             $mapped = array();
         }
     }
     // Don't check if string arguments are matching against the source,
     // as they might be generated HTML diff views instead of the actual values
     if ($this->value && !is_array($this->value) && !$mapped) {
         $mapped = array(trim($this->value));
         $values = array();
     }
     if ($mapped) {
         $attrValue = implode(', ', array_values($mapped));
         if (!$this->dontEscape) {
             $attrValue = Convert::raw2xml($attrValue);
         }
         $inputValue = implode(', ', array_values($values));
     } else {
         $attrValue = '<i>(' . _t('FormField.NONE', 'none') . ')</i>';
         $inputValue = '';
     }
     return "<span class=\"readonly\" id=\"" . $this->id() . "\">{$attrValue}</span><input type=\"hidden\" name=\"" . $this->name . "\" value=\"" . $inputValue . "\" />";
 }
 /**
  * Return the themes that can be used with this subsite, as an array of themecode => description
  */
 function allowedThemes()
 {
     if ($themes = $this->stat('allowed_themes')) {
         return ArrayLib::valuekey($themes);
     } else {
         $themes = array();
         if (is_dir('../themes/')) {
             foreach (scandir('../themes/') as $theme) {
                 if ($theme[0] == '.') {
                     continue;
                 }
                 $theme = strtok($theme, '_');
                 $themes[$theme] = $theme;
             }
             ksort($themes);
         }
         return $themes;
     }
 }
 public function getCMSFields()
 {
     $fields = parent::getCMSFields();
     $fields->removeFieldFromTab('Root', 'ViewerGroups');
     $viewersOptionsSource['LoggedInUsers'] = _t('TimedNotice.ACCESSLOGGEDIN', 'Logged-in users');
     $viewersOptionsSource['OnlyTheseUsers'] = _t('TimedNotice.ACCESSONLYTHESE', 'Only these people (choose from list)');
     $fields->addFieldToTab('Root.Main', $canViewTypeField = OptionsetField::create("CanViewType", _t('TimedNotice.ACCESSHEADER', "Who should see this notice?"), $viewersOptionsSource));
     $groupsMap = Group::get()->map('ID', 'Breadcrumbs')->toArray();
     asort($groupsMap);
     $fields->addFieldToTab('Root.Main', $viewerGroupsField = ListboxField::create("ViewerGroups", _t('TimedNotice.VIEWERGROUPS', "Only people in these groups"))->setMultiple(true)->setSource($groupsMap)->setAttribute('data-placeholder', _t('TimedNotice.GroupPlaceholder', 'Click to select group')));
     $viewerGroupsField->displayIf("CanViewType")->isEqualTo("OnlyTheseUsers");
     $fields->addFieldToTab('Root.Main', DropdownField::create('MessageType', 'Message Type', ArrayLib::valuekey($this->config()->get('message_types'))), 'Message');
     $fields->addFieldToTab('Root.Main', ReadonlyField::create('TZNote', 'Note', sprintf(_t('TimedNotice.TZNote', 'Your dates and times should be based on the server timezone: %s'), date_default_timezone_get())), 'StartTime');
     $start = $fields->dataFieldByName('StartTime');
     $end = $fields->dataFieldByName('EndTime');
     $start->getDateField()->setConfig('showcalendar', true);
     $end->getDateField()->setConfig('showcalendar', true);
     $start->setTimeField(TimePickerField::create('StartTime[time]', '')->addExtraClass('fieldgroup-field'));
     $end->setTimeField(TimePickerField::create('EndTime[time]', '')->addExtraClass('fieldgroup-field'));
     return $fields;
 }
 /**
  * this method returns an associative array of payment methods
  * available for the current order.
  *
  * @return array
  */
 public function SupportedMethods($order = null)
 {
     $hideTestPaymentMethods = false;
     if (Director::isLive()) {
         $hideTestPaymentMethods = false;
     }
     $supportedMethods = EcommerceConfig::get("EcommercePayment", "supported_methods");
     if (ArrayLib::is_associative($supportedMethods)) {
         if ($hideTestPaymentMethods) {
             if (count($supportedMethods)) {
                 foreach ($supportedMethods as $methodClass => $methodTitle) {
                     if (is_subclass_of($methodClass, "EcommercePayment_Test")) {
                         unset($supportedMethods[$methodClass]);
                     }
                 }
             }
         }
     } else {
         user_error('EcommercePayment::$supported_methods() requires an associative array. Right now the supported payments methods are: ' . print_r($supportedMethods, 1), E_USER_NOTICE);
     }
     return $supportedMethods;
 }