Created
January 27, 2019 10:51
-
-
Save bigin/7ace7c26314fc394b83a38498c3a0c09 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
$thisfile = basename(__FILE__, '.php'); | |
register_plugin( | |
$thisfile, | |
'ItemManager\'s Extension', | |
'0.1', | |
'Your name', | |
'https://your-site.com', | |
'An ItemManger admin extension.', | |
'', | |
'' | |
); | |
add_action('ImActivated', 'im_action'); | |
function im_action($manager) { | |
if(!class_exists('AdminExtended')) | |
{ | |
class AdminExtended extends Admin | |
{ | |
protected function callModelMethod($method, $args) | |
{ | |
if($method == 'saveItem') { | |
$this->beforeItemSave($args); | |
parent::callModelMethod($method, $args); | |
} elseif($method == 'deleteItem') { | |
$this->beforeItemDelete($args[0], $args[1]); | |
parent::callModelMethod($method, $args); | |
} else { | |
parent::callModelMethod($method, $args); | |
} | |
} | |
/** | |
* Here you can override native item-editor view of the ItemManager | |
* admin area. | |
*/ | |
protected function buildItemEditor() | |
{ | |
// Get the item ID | |
$id = !empty($this->input['edit']) ? (int) $this->input['edit'] : | |
(isset($this->input['iid']) ? (int) $this->input['iid'] : null); | |
// Get current category | |
$category = $this->manager->getCategoryMapper()->getCategory($this->manager->cp->currentCategory()); | |
// Run a native IM method if this isn't an item of a different category | |
if(!isset($category) || $category->name != 'Countries') { | |
return parent::buildItemEditor(); | |
} | |
//////////////////////////////////////////////////////////////////////////////////////////// | |
// | |
// OK, this seems to be an item of the category where you want to show your dropdown field. | |
// Below you could write your own code to show the Admin-Editor for the items, but I will | |
// just copy most of the code from the original function and only partly add my own logic | |
// to it. | |
// | |
//////////////////////////////////////////////////////////////////////////////////////////// | |
// Get our templates | |
$itemeditor = $this->tpl->getTemplates('itemeditor'); | |
// We comment default 'form' template out, since we will use our own - See below 'getEditorWrapper()' | |
// method. | |
//$form = $this->tpl->getTemplate('form', $itemeditor); | |
$fieldarea = $this->tpl->getTemplate('fieldarea', $itemeditor); | |
$infotext = $this->tpl->getTemplate('infotext', $itemeditor); | |
$required = $this->tpl->getTemplate('required', $itemeditor); | |
$categoryid = $category->id; | |
$backpage = !empty($this->input['page']) ? intval($this->input['page']) : 1; | |
$stamp = !empty($this->input['timestamp']) ? $this->input['timestamp'] : time(); | |
$ic = $this->manager->getItemMapper(); | |
$ic->limitedInit($categoryid, $id); | |
$curitem = !empty($ic->items[$id]) ? $ic->items[$id] : null; | |
// Is a new item | |
if(!$curitem) { | |
$curitem = new Item($categoryid); | |
$active = $this->manager->config->backend->itemactive; | |
} else { | |
$active = $curitem->active; | |
} | |
// | |
// Let's start building our dropdown right here: | |
// First we get all items from the category 'Cities' to display them in a dropdown field. | |
// | |
$citiesCategory = $this->manager->getCategoryMapper()->getCategory('name=Cities'); | |
$ic->alloc($citiesCategory->id); | |
// Get the value of the hidden field 'data' to retrieve already selected cities | |
$selected = !empty($curitem->fields->data->value) ? | |
unserialize(base64_decode($curitem->fields->data->value)) : []; | |
// Now, we're going through all the cities and build our dropdown list. | |
$options = ''; | |
if($ic->simpleItems) { | |
foreach($ic->simpleItems as $city) { | |
$options .= '<option value="'.$city->id.'"'. | |
(array_key_exists($city->id, $selected) ? ' selected': '').'>'.$city->name.'</option>'; | |
} | |
} | |
// Initialize the category fields | |
$fc = new FieldMapper(); | |
$fc->init($categoryid); | |
$fields = $fc->filterFields('position', 'asc'); | |
$tplfields = ''; | |
if($fields) | |
{ | |
foreach($fields as $fieldname => $field) | |
{ | |
// Input | |
$inputClassName = 'Input'.ucfirst($field->type); | |
$InputType = new $inputClassName($fields[$fieldname]); | |
$output = $InputType->prepareOutput(); | |
// Field | |
$fieldClassName = 'Field'.ucfirst($field->type); | |
$fieldType = new $fieldClassName($this->tpl); | |
$fieldType->name = $fieldname; | |
$fieldType->id = $fieldType->name; | |
if(!empty($field->configs)) | |
{ | |
foreach($field->configs as $key => $val) | |
{ | |
$fieldType->configs->$key = $val; | |
} | |
} | |
// Hidden | |
if($field->type == 'hidden') continue; | |
// Dropdown | |
if($field->type == 'dropdown') $fieldType->options = $field->options; | |
// File upload | |
if($field->type == 'fileupload') { | |
$fieldType->categoryid = $categoryid; | |
$fieldType->itemid = $id; | |
$fieldType->realid = $field->id; | |
$fieldType->timestamp = $stamp; | |
} | |
foreach($output as $outputkey => $outputvalue) | |
{ | |
$fieldType->class = empty($field->fieldclass) ? $field->type.'-field' : $field->fieldclass; | |
if(!empty($field->fieldcss)) | |
$fieldType->style = $field->fieldcss; | |
if(is_array($outputvalue)) | |
{ | |
$fieldType->$outputkey = array(); | |
$counter = 0; | |
if(!isset($curitem->fields->$fieldname->$outputkey)) | |
continue; | |
foreach($curitem->fields->$fieldname->$outputkey as $arrkey => $arrval) | |
{ | |
$fieldType->{$outputkey}[] = | |
(string) $curitem->fields->$fieldname->{$outputkey}[$counter]; | |
$counter++; | |
} | |
} else | |
$fieldType->$outputkey = !empty($curitem->fields->$fieldname->$outputkey) ? | |
(string) $curitem->fields->$fieldname->$outputkey : ''; | |
if(MsgReporter::isError()) | |
$fieldType->$outputkey = !empty($this->input[$fieldType->name]) ? | |
$this->input[$fieldType->name] : ''; | |
} | |
// Set default field values | |
if(empty($fieldType->value) && !empty($field->default)) | |
$fieldType->value = (string) $field->default; | |
$tplinfotext = ''; | |
if(!empty($field->info)) | |
$tplinfotext = $this->tpl->render($infotext, array('infotext' => $field->info)); | |
$tplrequired = ''; | |
if(!empty($field->required) && $field->required == 1) | |
$tplrequired = $this->tpl->render($required, array()); | |
if($field->type != 'chunk') | |
{ | |
$tplfields .= $this->tpl->render($fieldarea, array( | |
'fieldid' => $field->name, | |
'label' => $field->label, | |
'infotext' => $tplinfotext, | |
'area-class' => !empty($field->areaclass) ? $field->areaclass : 'fieldarea', | |
'area-style' => !empty($field->areacss) ? ' style="'.$field->areacss.'"' : '', | |
'label-class' => !empty($field->labelclass) ? $field->labelclass : '', | |
'label-style' => !empty($field->labelcss) ? ' style="'.$field->labelcss.'"' : '', | |
'required' => $tplrequired, | |
'field' => $fieldType->render()) | |
); | |
} else | |
{ | |
$tplfields .= $fieldType->render(); | |
} | |
} | |
} | |
// | |
// Take a look at this, here we use our modified wrapper template. | |
// | |
return $this->getEditorWrapper([ | |
'action_edit' => !is_null($id) ? $id : '', | |
'action_page' => $backpage, | |
'item-id' => $id, | |
'position' => !empty($curitem->position) ? $curitem->position : '', | |
'checked' => ($active > 0) ? ' checked ' : '', | |
'back-page' => $backpage, | |
'timestamp' => $stamp, | |
'infotext' => '', | |
'currentcategory' => $this->manager->cp->currentCategory(), | |
'itemname' => !empty($curitem->name) ? $curitem->name : '', | |
'options' => $options, | |
'custom-fields' => $tplfields, | |
'created' => ((int) $curitem->created > 0) ? | |
date((string) $this->manager->config->backend->timeformat, (int) $curitem->created) : '', | |
'updated' => ($curitem->updated > 0) ? | |
date((string) $this->manager->config->backend->timeformat, (int) $curitem->updated) : '' | |
] | |
); | |
} | |
/** | |
* Here you can write your own method that will be executed after | |
* someone saves an item via ItemManager's backend. | |
* | |
*/ | |
protected function beforeItemSave(& $input) | |
{ | |
// First check if this is the right category we want to edit, if not, we skip the function. | |
$category = $this->manager->getCategoryMapper()->getCategory($this->manager->cp->currentCategory()); | |
if(!isset($category) || $category->name != 'Countries') return; | |
// Now, catch the value of our dropdown field and | |
// prepare its contents for saving into the hidden field. | |
$selected = []; | |
if(isset($input['cities']) && !empty($input['cities'])) { | |
// Get our cities, because we also want to adopt the city names in our array | |
$mapper = $this->manager->getItemMapper(); | |
$citiesCategory = $this->manager->getCategoryMapper()->getCategory('name=Cities'); | |
if(!$citiesCategory) return; | |
$mapper->alloc($citiesCategory->id); | |
if($mapper->simpleItems) { | |
foreach($mapper->simpleItems as $city) { | |
if(in_array($city->id, $input['cities'])) { | |
$selected[$city->id] = $city->name; | |
} | |
} | |
} | |
} | |
// Serialize the $selected arry to save it as hidden field value. | |
$input['data'] = base64_encode(serialize($selected)); | |
} | |
/** | |
* Here you can write your own method that will be executed before | |
* someone deletes an item via ItemManager's backend. | |
* | |
* Something troublesome is if we want to delete a city from our cities list, | |
* since we now have to go through all our countries to remove the deleted | |
* city ID from the selected cities array again. | |
* | |
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * | |
* MOTE: If there are many items (Countries), it can slow down the script | |
* extremely, because we have to unserialize every single data field value | |
* to check its contents | |
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * | |
*/ | |
protected function beforeItemDelete($id, $catid) | |
{ | |
// First check if this is the right category we want to edit, if not, we skip the function. | |
$category = $this->manager->getCategoryMapper()->getCategory($this->manager->cp->currentCategory()); | |
if(!isset($category) || $category->name != 'Cities') return; | |
// Now let's retrieve all the countries and in case there is the deleted | |
// city there, we will delete this out there. | |
$countryCategory = $this->manager->getCategoryMapper()->getCategory('name=Countries'); | |
if(!$countryCategory) return; | |
$mapper = $this->manager->getItemMapper(); | |
$mapper->init($countryCategory->id); | |
$mapper->alloc($countryCategory->id); | |
$countries = $mapper->items; | |
if(!$countries) return; | |
foreach($countries as $country) { | |
$selected = !empty($country->fields->data->value) ? | |
unserialize(base64_decode($country->fields->data->value)) : []; | |
// Remove deletet city from the array | |
if(array_key_exists($id, $selected)) | |
{ | |
unset($selected[$id]); | |
$country->fields->data->value = base64_encode(serialize($selected)); | |
$country->save(); | |
$mapper->simplify($country); | |
$mapper->save(); | |
} | |
} | |
} | |
private function getEditorWrapper(array $data = []) | |
{ | |
ob_start(); | |
?> | |
<div class="manager-wrapper"> | |
<h3 class="menuglava">Create / Edit Item</h3> | |
<form class="largeform" action="load.php?id=imanager&edit=<?php echo $data['action_edit']; | |
?>&page=<?php echo $data['action_page']; ?>" method="post" enctype="multipart/form-data" | |
accept-charset="utf-8"> | |
<input name="iid" type="hidden" value="<?php echo $data['item-id']; ?>"> | |
<input name="page" type="hidden" value="<?php echo $data['back-page']; ?>" > | |
<input name="categoryid" type="hidden" value="<?php echo $data['currentcategory']; ?>"> | |
<input name="timestamp" type="hidden" value="<?php echo $data['timestamp']; ?>"> | |
<div> | |
<div class="fieldarea"> | |
<label for="catid" class="im-left">ID</label> | |
<p id="catid" class="im-cat-info"><?php echo $data['item-id']; ?></p> | |
</div> | |
<div class="fieldarea"> | |
<label for="title">Title</label> | |
<div class="field-wrapper"> | |
<input id="title" class="im-title" name="name" type="text" | |
value="<?php echo $data['itemname']; ?>"> | |
</div> | |
</div> | |
<!-- [ DROPDOWN ] --> | |
<div class="fieldarea"> | |
<label for="title">Cities</label> | |
<div class="field-wrapper"> | |
<select name="cities[]" style="background:none" multiple> | |
<?php echo $data['options']; ?> | |
</select> | |
</div> | |
</div> | |
<!-- [ /DROPDOWN ] --> | |
<div class="fieldarea"> | |
<label for="position">Position</label> | |
<div class="field-wrapper"> | |
<input id="position" name="itempos" type="number" value="<?php | |
echo $data['position']; ?>"> | |
</div> | |
</div> | |
<div class="fieldarea"> | |
<label for="active">Enabled</label> | |
<div class="field-wrapper"> | |
<input id="active" name="active" type="checkbox" value="1" <?php | |
echo $data['checked']; ?>> | |
</div> | |
</div> | |
<?php echo $data['custom-fields']; ?> | |
<div class="fieldarea"> | |
<label for="itemcreated" >Created date</label> | |
<div class="field-wrapper"><?php echo $data['created']; ?></div> | |
</div> | |
<div class="fieldarea"> | |
<label for="itemcreated" >Modified</label> | |
<div class="field-wrapper"><?php echo $data['updated']; ?></div> | |
</div> | |
<p><input name="submit" type="submit" class="submit" value="Save"></p> | |
</div> | |
</form> | |
</div> | |
<?php return ob_get_clean(); | |
} | |
} | |
$newbackend = new \AdminExtended; | |
$manager->setAdmin($newbackend); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment