public static function include_js()
 {
     $availableConfigs = HtmlEditorConfig::get_available_configs_map();
     foreach ($availableConfigs as $identifier => $friendlyName) {
         self::include_js_internal($identifier);
     }
 }
    /**
     * This basically merges HtmlEditorField::include_js() and HTMLEditorConfig::generateJS() to output all
     * configuration sets to a customTinyMceConfigs javascript array.
     * This is output in addition to the standard ssTinyMceConfig because a) we can't stop the default output
     * with extensions; and b) the default setting is still used for any HTMLEditorField that doesn't specify
     * it's own config.
     *
     * Calls Requirements::javascript() to load the scripts.
     */
    public static function include_js()
    {
        require_once 'tinymce/tiny_mce_gzip.php';
        $availableConfigs = HtmlEditorConfig::get_available_configs_map();
        $pluginsForTag = array();
        $languages = array();
        //$allConfigs = array();
        $settingsJS = '';
        $externalPluginsForJS = array();
        $activeConfig = HtmlEditorConfig::get_active();
        foreach ($availableConfigs as $identifier => $friendlyName) {
            $configObj = CustomHtmlEditorConfig::get($identifier);
            $internalPluginsForJS = array();
            $configObj->getConfig()->setOption('language', i18n::get_tinymce_lang());
            if (!$configObj->getConfig()->getOption('content_css')) {
                $configObj->getConfig()->setOption('content_css', $activeConfig->getOption('content_css'));
            }
            $settings = $configObj->getSettings();
            foreach ($configObj->getPlugins() as $plugin => $path) {
                if (!$path) {
                    $pluginsForTag[$plugin] = $plugin;
                    $internalPluginsForJS[$plugin] = $plugin;
                } else {
                    $internalPluginsForJS[$plugin] = '-' . $plugin;
                    $externalPluginsForJS[$plugin] = sprintf('tinymce.PluginManager.load("%s", "%s");' . "\n", $plugin, $path);
                }
            }
            $language = $configObj->getConfig()->getOption('language');
            if ($language) {
                $languages[$language] = $language;
            }
            $settings['plugins'] = implode(',', $internalPluginsForJS);
            $buttons = $configObj->getButtons();
            foreach ($buttons as $i => $buttons) {
                $settings['theme_advanced_buttons' . $i] = implode(',', $buttons);
            }
            $settingsJS .= "customTinyMceConfigs['" . $identifier . "'] = " . Convert::raw2json($settings) . ";\n";
        }
        if (Config::inst()->get('HtmlEditorField', 'use_gzip')) {
            $tag = TinyMCE_Compressor::renderTag(array('url' => THIRDPARTY_DIR . '/tinymce/tiny_mce_gzip.php', 'plugins' => implode(',', $pluginsForTag), 'themes' => 'advanced', 'languages' => implode(',', $languages)), true);
            preg_match('/src="([^"]*)"/', $tag, $matches);
            Requirements::javascript($matches[1]);
        } else {
            Requirements::javascript(MCE_ROOT . 'tiny_mce_src.js');
        }
        $externalPluginsJS = implode('', $externalPluginsForJS);
        $script = <<<JS
\t\t\tif((typeof tinyMCE != 'undefined')) {
\t\t\t\t{$externalPluginsJS}

\t\t\t\tif (typeof customTinyMceConfigs == 'undefined') {
\t\t\t\t\tvar customTinyMceConfigs = [];
\t\t\t\t}
\t\t\t\t{$settingsJS}
\t\t\t}

JS;
        Requirements::customScript($script, 'htmlEditorConfigs');
    }
Example #3
0
 /**
  * Caution: Only call on instances, not through a singleton.
  *
  * @return FieldSet
  */
 public function getCMSFields()
 {
     $fields = new FieldSet(new TabSet("Root", new Tab(_t('SecurityAdmin.MEMBERS', 'Members'), new TextField("Title", $this->fieldLabel('Title')), $memberList = new MemberTableField($this, "Members", $this, null, false)), new Tab(_t('SecurityAdmin.PERMISSIONS', 'Permissions'), new LiteralField("", "<p>" . _t('SecurityAdmin.ADVANCEDONLY', "This section is for advanced users only.\n\t\t\t\t\t\t\tSee <a href=\"http://doc.silverstripe.com/doku.php?id=permissions:codes\" target=\"_blank\">this page</a>\n\t\t\t\t\t\t\tfor more information.") . "</p>"), new DropdownField('HtmlEditorConfig', 'HTML Editor Configuration', HtmlEditorConfig::get_available_configs_map()), new TableField("Permissions", "Permission", array("Code" => _t('SecurityAdmin.CODE', 'Code'), "Arg" => _t('SecurityAdmin.OPTIONALID', 'Optional ID')), array("Code" => "PermissionDropdownField", "Arg" => "TextField"), "GroupID", $this->ID)), new Tab(_t('Security.IPADDRESSES', 'IP Addresses'), new LiteralField("", _t('SecurityAdmin.IPADDRESSESHELP', "<p>You can restrict this group to a particular \n\t\t\t\t\t\tIP address range (one range per line). <br />Ranges can be in any of the following forms: <br />\n\t\t\t\t\t\t203.96.152.12<br />\n\t\t\t\t\t\t203.96.152/24<br />\n\t\t\t\t\t\t203.96/16<br />\n\t\t\t\t\t\t203/8<br /><br />If you enter one or more IP address ranges in this box, then members will only get\n\t\t\t\t\t\tthe rights of being in this group if they log on from one of the valid IP addresses.  It won't prevent\n\t\t\t\t\t\tpeople from logging in.  This is because the same user might have to log in to access parts of the\n\t\t\t\t\t\tsystem without IP address restrictions.")), new TextareaField("IPRestrictions", "IP Ranges", 10))));
     if (!Permission::check('EDIT_PERMISSIONS')) {
         $fields->removeFieldFromTab('Root', 'Permissions');
         $fields->removeFieldFromTab('Root', 'IP Addresses');
     }
     $memberList->setController($this);
     $memberList->setPermissions(array('show', 'edit', 'delete', 'export', 'add'));
     $memberList->setParentClass('Group');
     $memberList->setPopupCaption(_t('SecurityAdmin.VIEWUSER', 'View User'));
     $fields->push($idField = new HiddenField("ID"));
     $this->extend('updateCMSFields', $fields);
     return $fields;
 }
Example #4
0
 /**
  * Caution: Only call on instances, not through a singleton.
  *
  * @return FieldSet
  */
 public function getCMSFields()
 {
     $fields = new FieldSet(new TabSet("Root", new Tab(_t('SecurityAdmin.MEMBERS', 'Members'), new TextField("Title", $this->fieldLabel('Title')), $memberList = new MemberTableField($this, "Members", $this, null, false)), $permissionsTab = new Tab(_t('SecurityAdmin.PERMISSIONS', 'Permissions'), new PermissionCheckboxSetField('Permissions', false, 'Permission', 'GroupID', $this)), new Tab(_t('Security.IPADDRESSES', 'IP Addresses'), new LiteralField("", _t('SecurityAdmin.IPADDRESSESHELP', "<p>You can restrict this group to a particular \n\t\t\t\t\t\tIP address range (one range per line). <br />Ranges can be in any of the following forms: <br />\n\t\t\t\t\t\t203.96.152.12<br />\n\t\t\t\t\t\t203.96.152/24<br />\n\t\t\t\t\t\t203.96/16<br />\n\t\t\t\t\t\t203/8<br /><br />If you enter one or more IP address ranges in this box, then members will only get\n\t\t\t\t\t\tthe rights of being in this group if they log on from one of the valid IP addresses.  It won't prevent\n\t\t\t\t\t\tpeople from logging in.  This is because the same user might have to log in to access parts of the\n\t\t\t\t\t\tsystem without IP address restrictions.")), new TextareaField("IPRestrictions", "IP Ranges", 10))));
     // Only add a dropdown for HTML editor configurations if more than one is available.
     // Otherwise Member->getHtmlEditorConfigForCMS() will default to the 'cms' configuration.
     $editorConfigMap = HtmlEditorConfig::get_available_configs_map();
     if (count($editorConfigMap) > 1) {
         $fields->addFieldToTab('Root.Permissions', new DropdownField('HtmlEditorConfig', 'HTML Editor Configuration', $editorConfigMap), 'Permissions');
     }
     if (!Permission::check('EDIT_PERMISSIONS')) {
         $fields->removeFieldFromTab('Root', 'Permissions');
         $fields->removeFieldFromTab('Root', 'IP Addresses');
     }
     // Only show the "Roles" tab if permissions are granted to edit them,
     // and at least one role exists
     if (Permission::check('APPLY_ROLES') && DataObject::get('PermissionRole')) {
         $fields->findOrMakeTab('Root.Roles', _t('SecurityAdmin.ROLES', 'Roles'));
         $fields->addFieldToTab('Root.Roles', new LiteralField("", "<p>" . _t('SecurityAdmin.ROLESDESCRIPTION', "This section allows you to add roles to this group. Roles are logical groupings of permissions, which can be editied in the Roles tab") . "</p>"));
         // Add roles (and disable all checkboxes for inherited roles)
         $allRoles = Permission::check('ADMIN') ? DataObject::get('PermissionRole') : DataObject::get('PermissionRole', 'OnlyAdminCanApply = 0');
         $groupRoles = $this->Roles();
         $inheritedRoles = new DataObjectSet();
         $ancestors = $this->getAncestors();
         foreach ($ancestors as $ancestor) {
             $ancestorRoles = $ancestor->Roles();
             if ($ancestorRoles) {
                 $inheritedRoles->merge($ancestorRoles);
             }
         }
         $fields->findOrMakeTab('Root.Roles', 'Root.' . _t('SecurityAdmin.ROLES', 'Roles'));
         $fields->addFieldToTab('Root.Roles', $rolesField = new CheckboxSetField('Roles', 'Roles', $allRoles));
         $rolesField->setDefaultItems($inheritedRoles->column('ID'));
         $rolesField->setDisabledItems($inheritedRoles->column('ID'));
     }
     $memberList->setController($this);
     $memberList->setPermissions(array('edit', 'delete', 'export', 'add', 'inlineadd'));
     $memberList->setParentClass('Group');
     $memberList->setPopupCaption(_t('SecurityAdmin.VIEWUSER', 'View User'));
     $memberList->setRelationAutoSetting(false);
     $fields->push($idField = new HiddenField("ID"));
     $this->extend('updateCMSFields', $fields);
     return $fields;
 }
 /**
  * Caution: Only call on instances, not through a singleton.
  * The "root group" fields will be created through {@link SecurityAdmin->EditForm()}.
  *
  * @return FieldList
  */
 public function getCMSFields()
 {
     Requirements::javascript(FRAMEWORK_DIR . '/javascript/PermissionCheckboxSetField.js');
     $fields = new FieldList(new TabSet("Root", new Tab('Members', _t('SecurityAdmin.MEMBERS', 'Members'), new TextField("Title", $this->fieldLabel('Title')), $parentidfield = DropdownField::create('ParentID', $this->fieldLabel('Parent'), Group::get()->exclude('ID', $this->ID)->map('ID', 'Breadcrumbs'))->setEmptyString(' '), new TextareaField('Description', $this->fieldLabel('Description'))), $permissionsTab = new Tab('Permissions', _t('SecurityAdmin.PERMISSIONS', 'Permissions'), $permissionsField = new PermissionCheckboxSetField('Permissions', false, 'Permission', 'GroupID', $this))));
     $parentidfield->setDescription(_t('Group.GroupReminder', 'If you choose a parent group, this group will take all it\'s roles'));
     // Filter permissions
     // TODO SecurityAdmin coupling, not easy to get to the form fields through GridFieldDetailForm
     $permissionsField->setHiddenPermissions((array) Config::inst()->get('SecurityAdmin', 'hidden_permissions'));
     if ($this->ID) {
         $group = $this;
         $config = GridFieldConfig_RelationEditor::create();
         $config->addComponent(new GridFieldButtonRow('after'));
         $config->addComponents(new GridFieldExportButton('buttons-after-left'));
         $config->addComponents(new GridFieldPrintButton('buttons-after-left'));
         $config->getComponentByType('GridFieldAddExistingAutocompleter')->setResultsFormat('$Title ($Email)')->setSearchFields(array('FirstName', 'Surname', 'Email'));
         $config->getComponentByType('GridFieldDetailForm')->setValidator(new Member_Validator())->setItemEditFormCallback(function ($form, $component) use($group) {
             $record = $form->getRecord();
             $groupsField = $form->Fields()->dataFieldByName('DirectGroups');
             if ($groupsField) {
                 // If new records are created in a group context,
                 // set this group by default.
                 if ($record && !$record->ID) {
                     $groupsField->setValue($group->ID);
                 } elseif ($record && $record->ID) {
                     // TODO Mark disabled once chosen.js supports it
                     // $groupsField->setDisabledItems(array($group->ID));
                     $form->Fields()->replaceField('DirectGroups', $groupsField->performReadonlyTransformation());
                 }
             }
         });
         $memberList = GridField::create('Members', false, $this->DirectMembers(), $config)->addExtraClass('members_grid');
         // @todo Implement permission checking on GridField
         //$memberList->setPermissions(array('edit', 'delete', 'export', 'add', 'inlineadd'));
         $fields->addFieldToTab('Root.Members', $memberList);
     }
     // Only add a dropdown for HTML editor configurations if more than one is available.
     // Otherwise Member->getHtmlEditorConfigForCMS() will default to the 'cms' configuration.
     $editorConfigMap = HtmlEditorConfig::get_available_configs_map();
     if (count($editorConfigMap) > 1) {
         $fields->addFieldToTab('Root.Permissions', new DropdownField('HtmlEditorConfig', 'HTML Editor Configuration', $editorConfigMap), 'Permissions');
     }
     if (!Permission::check('EDIT_PERMISSIONS')) {
         $fields->removeFieldFromTab('Root', 'Permissions');
     }
     // Only show the "Roles" tab if permissions are granted to edit them,
     // and at least one role exists
     if (Permission::check('APPLY_ROLES') && DataObject::get('PermissionRole')) {
         $fields->findOrMakeTab('Root.Roles', _t('SecurityAdmin.ROLES', 'Roles'));
         $fields->addFieldToTab('Root.Roles', new LiteralField("", "<p>" . _t('SecurityAdmin.ROLESDESCRIPTION', "Roles are predefined sets of permissions, and can be assigned to groups.<br />" . "They are inherited from parent groups if required.") . '<br />' . sprintf('<a href="%s" class="add-role">%s</a>', singleton('SecurityAdmin')->Link('show/root#Root_Roles'), _t('Group.RolesAddEditLink', 'Manage roles')) . "</p>"));
         // Add roles (and disable all checkboxes for inherited roles)
         $allRoles = PermissionRole::get();
         if (!Permission::check('ADMIN')) {
             $allRoles = $allRoles->filter("OnlyAdminCanApply", 0);
         }
         if ($this->ID) {
             $groupRoles = $this->Roles();
             $inheritedRoles = new ArrayList();
             $ancestors = $this->getAncestors();
             foreach ($ancestors as $ancestor) {
                 $ancestorRoles = $ancestor->Roles();
                 if ($ancestorRoles) {
                     $inheritedRoles->merge($ancestorRoles);
                 }
             }
             $groupRoleIDs = $groupRoles->column('ID') + $inheritedRoles->column('ID');
             $inheritedRoleIDs = $inheritedRoles->column('ID');
         } else {
             $groupRoleIDs = array();
             $inheritedRoleIDs = array();
         }
         $rolesField = ListboxField::create('Roles', false, $allRoles->map()->toArray())->setDefaultItems($groupRoleIDs)->setAttribute('data-placeholder', _t('Group.AddRole', 'Add a role for this group'))->setDisabledItems($inheritedRoleIDs);
         if (!$allRoles->Count()) {
             $rolesField->setAttribute('data-placeholder', _t('Group.NoRoles', 'No roles found'));
         }
         $fields->addFieldToTab('Root.Roles', $rolesField);
     }
     $fields->push($idField = new HiddenField("ID"));
     $this->extend('updateCMSFields', $fields);
     return $fields;
 }
 /**
  * Prepares everything just before rendering the field
  */
 protected function prepareForRender()
 {
     if (!$this->preparedForRender) {
         $this->preparedForRender = true;
         if (!$this->isReadonly() && $this->depth == 1) {
             // NOTE(Jake): jQuery.ondemand is required to allow FormField classes to add their own
             //             Requirements::javascript on-the-fly.
             //Requirements::javascript(FRAMEWORK_DIR . "/thirdparty/jquery/jquery.js");
             Requirements::css(MULTIRECORDEDITOR_DIR . '/css/MultiRecordField.css');
             if (is_subclass_of(Controller::curr(), 'LeftAndMain')) {
                 // NOTE(Jake): Only include in CMS to fix margin issues. Not in the main CSS file
                 //             so that the frontend CSS is less in the way.
                 Requirements::css(MULTIRECORDEDITOR_DIR . '/css/MultiRecordFieldCMS.css');
             }
             Requirements::css(THIRDPARTY_DIR . '/jquery-ui-themes/smoothness/jquery-ui.css');
             Requirements::javascript(FRAMEWORK_DIR . '/thirdparty/jquery-ui/jquery-ui.js');
             Requirements::javascript(FRAMEWORK_DIR . '/javascript/jquery-ondemand/jquery.ondemand.js');
             Requirements::javascript(THIRDPARTY_DIR . '/jquery-entwine/dist/jquery.entwine-dist.js');
             Requirements::javascript(MULTIRECORDEDITOR_DIR . '/javascript/MultiRecordField.js');
             // If config is set to 'default' but 'default' isn't configured, fallback to 'cms'.
             // NOTE(Jake): In SS 3.2, 'default' is the default active config but its not configured.
             $availableConfigs = HtmlEditorConfig::get_available_configs_map();
             $activeIdentifier = HtmlEditorConfig::get_active_identifier();
             if ($activeIdentifier === 'default' && !isset($availableConfigs[$activeIdentifier])) {
                 HtmlEditorConfig::set_active('cms');
             }
         }
         //
         // Setup actions
         //
         $actions = $this->Actions();
         if ($actions && $actions->count()) {
             $modelClasses = $this->getModelClassesOrThrowExceptionIfEmpty();
             $modelFirstClass = key($modelClasses);
             $inlineAddButton = $actions->dataFieldByName('action_AddInlineRecord');
             if ($inlineAddButton) {
                 // Setup default inline field data attributes
                 //$inlineAddButton->setAttribute('data-name', $this->getName());
                 $inlineAddButton->setAttribute('data-action', $this->getName());
                 $inlineAddButton->setAttribute('data-class', $modelFirstClass);
                 $inlineAddButton->setAttribute('data-depth', $this->depth);
                 // Automatically apply all data attributes on this element, to the inline button.
                 foreach ($this->getAttributes() as $name => $value) {
                     if (substr($name, 0, 5) === 'data-') {
                         $inlineAddButton->setAttribute($name, $value);
                     }
                 }
                 if (count($modelClasses) == 1) {
                     $name = singleton($modelFirstClass)->i18n_singular_name();
                     $inlineAddButton->setTitle('Add ' . $name);
                 }
             }
             $classField = $actions->dataFieldByName('ClassName');
             if ($classField) {
                 if (count($modelClasses) > 1) {
                     if ($inlineAddButton) {
                         $inlineAddButton->setDisabled(true);
                     }
                     $classField->setSource($modelClasses);
                 } else {
                     $actions->removeByName('ClassName');
                 }
             }
             // Allow outside sources to influences the disable state class-wise
             if ($inlineAddButton && $inlineAddButton->isDisabled()) {
                 $inlineAddButton->addExtraClass('is-disabled');
             }
             //
             foreach ($actions as $actionField) {
                 // Expand out names
                 $actionField->setName($this->getName() . '_' . $actionField->getName());
             }
         }
         // Get existing records to add fields for
         $recordArray = array();
         if ($this->list && !$this->list instanceof UnsavedRelationList) {
             foreach ($this->list->toArray() as $record) {
                 $recordArray[$record->ID] = $record;
             }
         }
         //
         // If the user validation failed, Value() will be populated with some records
         // that have 'new_' IDs, so handle them.
         //
         $value = $this->Value();
         if ($value && is_array($value)) {
             foreach ($value as $class => $recordDatas) {
                 foreach ($recordDatas as $new_id => $fieldData) {
                     if (substr($new_id, 0, 4) === 'new_') {
                         $record = $class::create();
                         $record->MultiRecordField_NewID = $new_id;
                         $recordArray[$new_id] = $record;
                     } else {
                         if ($new_id == (string) (int) $new_id) {
                             // NOTE(Jake): "o-multirecordediting-1-id" == 0 // evaluates true in PHP 5.5.12,
                             //             So we need to make it a string again to avoid that dumb case.
                             $new_id = (int) $new_id;
                             if (!isset($recordArray[$new_id])) {
                                 throw new Exception('Record #' . $new_id . ' does not exist in this context.');
                             }
                             $record = $recordArray[$new_id];
                             //throw new Exception('todo, handle existing stuff that fails validation. ('.$new_id.')');
                         } else {
                             throw new Exception('Validation failed and unable to restore fields with invalid ID. (' . $new_id . ')');
                         }
                     }
                     // Update new/existing record with data
                     foreach ($fieldData as $fieldName => $fieldInfo) {
                         if (is_array($fieldInfo)) {
                             $record->{$fieldName} = $fieldInfo;
                         } else {
                             $record->{$fieldName} = $fieldInfo->value;
                         }
                     }
                 }
             }
         }
         // Transform into list
         $recordList = new ArrayList($recordArray);
         // Ensure all the records are sorted by the sort field
         $sortFieldName = $this->getSortFieldName();
         if ($sortFieldName) {
             $recordList = $recordList->sort($sortFieldName);
         }
         //
         // Return all fields from the records editing
         //
         foreach ($recordList as $record) {
             $recordFields = $this->getRecordDataFields($record);
             $this->applyUniqueFieldNames($recordFields, $record);
             foreach ($recordFields as $field) {
                 $this->children->push($field);
             }
         }
     }
 }