/** * Define the form elements. */ private function _registerElements() { // Title: $this->addElement('text', 'title', array('label' => __('Title'), 'description' => __('A top-level heading for the exhibit, displayed in the page header in the public view for the exhibit.'), 'value' => $this->exhibit->title, 'required' => true, 'size' => 40, 'validators' => array(array('validator' => 'NotEmpty', 'breakChainOnFailure' => true, 'options' => array('messages' => array(Zend_Validate_NotEmpty::IS_EMPTY => __('Enter a title.'))))))); // Slug: $this->addElement('text', 'slug', array('label' => __('URL Slug'), 'description' => __('A unique string used to form the public-facing URL for the exhibit. Can contain letters, numbers, and hyphens.'), 'value' => $this->exhibit->slug, 'required' => true, 'size' => 40, 'filters' => array('StringTrim'), 'validators' => array(array('validator' => 'NotEmpty', 'breakChainOnFailure' => true, 'options' => array('messages' => array(Zend_Validate_NotEmpty::IS_EMPTY => __('Enter a slug.')))), array('validator' => 'Regex', 'breakChainOnFailure' => true, 'options' => array('pattern' => '/^[0-9a-z\\-]+$/', 'messages' => array(Zend_Validate_Regex::NOT_MATCH => __('The slug can only contain letters, numbers, and hyphens.')))), array('validator' => 'Db_NoRecordExists', 'options' => array('table' => $this->exhibit->getTable()->getTableName(), 'adapter' => $this->exhibit->getDb()->getAdapter(), 'field' => 'slug', 'exclude' => array('field' => 'id', 'value' => (int) $this->exhibit->id), 'messages' => array('recordFound' => __('The slug is already in use.'))))))); // Narrative: $this->addElement('textarea', 'narrative', array('label' => __('Narrative'), 'description' => __('A long-format prose narrative to accompany exhibit.'), 'value' => $this->exhibit->narrative, 'attribs' => array('rows' => '10'))); // Widgets: $this->addElement('multiselect', 'widgets', array('label' => __('Widgets'), 'description' => __('Select the user-interface widgets available in the exhibit.'), 'attribs' => array('data-placeholder' => 'Select one or more widgets', 'class' => 'chosen'), 'multiOptions' => array_flip(nl_getExhibitWidgets()), 'value' => nl_explode($this->exhibit->widgets))); // Available Map Layers: $this->addElement('multiselect', 'spatial_layers', array('label' => __('Enabled Spatial Layers'), 'description' => __('Choose the collection of spatial layers that should be available in the layer picker widget.'), 'attribs' => array('data-placeholder' => 'Select one or more layers', 'class' => 'chosen'), 'multiOptions' => nl_getLayersForSelect(), 'value' => nl_explode($this->exhibit->spatial_layers))); // Default Map Layer: $this->addElement('select', 'spatial_layer', array('label' => __('Default Spatial Layer'), 'description' => __('Select which of the spatial layers should be visible by default when the exhibit starts.'), 'attribs' => array('data-placeholder' => 'Select a layer', 'class' => 'chosen'), 'multiOptions' => nl_getLayersForSelect(), 'value' => nl_explode($this->exhibit->spatial_layer), 'required' => true, 'validators' => array(array('validator' => 'NotEmpty', 'breakChainOnFailure' => true, 'options' => array('messages' => array(Zend_Validate_NotEmpty::IS_EMPTY => __('Select a layer.'))))))); // Image Layer: $this->addElement('text', 'image_layer', array('label' => __('Image Layer'), 'description' => __('To use a static image as the base layer of the exhibit, enter the web-accessible location of the image.'), 'value' => $this->exhibit->image_layer, 'size' => 40)); // Zoom Levels: $this->addElement('text', 'zoom_levels', array('label' => __('Zoom Levels'), 'description' => __('Enter the number of zoom levels available for the static image.'), 'value' => $this->exhibit->zoom_levels, 'required' => true, 'size' => 40, 'validators' => array(array('validator' => 'NotEmpty', 'breakChainOnFailure' => true, 'options' => array('messages' => array(Zend_Validate_NotEmpty::IS_EMPTY => __('Enter a zoom level count.')))), array('validator' => 'Int', 'breakChainOnFailure' => true, 'options' => array('messages' => array(Zend_Validate_Int::NOT_INT => __('Must be an integer.'))))))); // WMS Address: $this->addElement('text', 'wms_address', array('label' => __('WMS Address'), 'description' => __('To use a custom WMS layer as the base layer of the exhibit, enter (a) the address of the WMS server.'), 'value' => $this->exhibit->wms_address, 'size' => 40)); // WMS Layers: $this->addElement('text', 'wms_layers', array('label' => __('WMS Layers'), 'description' => __('And (b) the comma-delimited list of layers.'), 'value' => $this->exhibit->wms_layers, 'size' => 40)); // Spatial Querying: $this->addElement('checkbox', 'spatial_querying', array('label' => __('Spatial Querying'), 'description' => __('If checked, the map will continously update to display just the records that fall inside the current viewport.'), 'value' => $this->exhibit->spatial_querying)); // Public: $this->addElement('checkbox', 'public', array('label' => __('Public'), 'description' => __('By default, exhibits are visible only to site administrators. Check here to publish the exhibit to the public site.'), 'value' => $this->exhibit->public)); // Submit: $this->addElement('submit', 'submit', array('label' => __('Save Exhibit'))); $this->addDisplayGroup(array('title', 'slug', 'narrative', 'widgets', 'spatial_layers', 'spatial_layer', 'image_layer', 'zoom_levels', 'wms_address', 'wms_layers', 'spatial_querying', 'public'), 'fields'); $this->addDisplayGroup(array('submit'), 'submit_button'); }
/** * Get a cropped array of layer definitions for an exhibit. * * @param NeatlineExhibit $exhibit The exhibit. * @return array The layers. */ function nl_getLayersForExhibit($exhibit) { $groups = nl_getLayers(); $subset = array(); // Explode the list of layer IDs in `spatial_layers` and merge the // `spatial_layer` slug into the array, which ensures that at least one // layer is included if `spatial_layers` is empty. $ids = nl_explode($exhibit->spatial_layers); $ids = array_merge($ids, array($exhibit->spatial_layer)); // Walk the layer groups. foreach ($groups as $group => $layers) { // Include the layer if it is enabled in the exhihbit. foreach ($layers as $layer) { if (in_array($layer['id'], $ids)) { $subset[] = $layer; } } } return $subset; }
/** * Save data from a POST or PUT request. * * @param array $values The POST/PUT values. */ public function saveForm($values) { // Cache the original tags string. $oldTags = nl_explode($this->tags); // Mass-assign the form. $this->setArray($values); // (1) Pull styles for new tags from the exhibit stylesheet. $newTags = nl_explode($this->tags); $this->pullStyles(array_diff($newTags, $oldTags)); $this->save(); // (2) Update the exhibit stylesheet with the record values. $exhibit = $this->getExhibit(); $exhibit->pullStyles($this); $exhibit->save(); // (3) Propagate the updated styles to sibling records. $exhibit->pushStyles(); }
/** * Get a list of space-delimited exhibit widget tags for use as the value * of a `class` attribute on an element. * * @param NeatlineExhibit $exhibit The exhibit. * @return string The space-delimited attribute value. */ function nl_getExhibitWidgetClasses($exhibit = null) { $exhibit = $exhibit ? $exhibit : nl_getExhibit(); return implode(' ', nl_explode($exhibit->widgets)); }
/** * Remove spaces. */ public function testRemoveSpaces() { $this->assertEquals(array('1', '2', '3'), nl_explode('1, 2, 3')); }
/** * Update the exhibit stylesheet with values from a specific record. For * example, if `styles` is: * * .tag { * fill-color: #111111; * stroke-color: #222222; * } * * And the record is tagged with `tag` has a `fill_color` of `#333333` and * a `stroke_color` of `#444444`, the stylesheet would be updated to: * * .tag { * fill-color: #333333; * stroke-color: #444444; * } * * @param NeatlineRecord $record The record to update from. */ public function pullStyles($record) { // Parse the stylesheet. $css = nl_readCSS($this->styles); // Explode record tags. $tags = nl_explode($record->tags); // Gather style columns. $valid = nl_getStyles(); foreach ($css as $selector => $rules) { // Is the record tagged with the selector? if (in_array($selector, $tags) || $selector == 'all') { // Scan valid rule definitions. foreach ($rules as $prop => $val) { // Is the property valid? if (in_array($prop, $valid)) { // Get the record value. $value = !is_null($record->{$prop}) ? $record->{$prop} : 'none'; // Update the CSS. $css[$selector][$prop] = $value; } } } } // Recompile the stylesheet. $this->styles = nl_writeCSS($css); }