Tree
Model → table
<?phpnamespace App\Model\Table;
use Cake\ORM\Query;use Cake\ORM\RulesChecker;use Cake\ORM\Table;use Cake\Validation\Validator;
class CategoriesTable extends Table { public function initialize(array $config) { parent::initialize($config);
$this->addBehavior('Translate', [ 'fields' => ['name'], 'translationTable' => 'I18n' ]);
$this->setTable('categories'); $this->setDisplayField('name'); $this->setPrimaryKey('id');
$this->addBehavior('Timestamp'); $this->addBehavior('Tree', [ 'recoverOrder' => ['name' => 'DESC'], ]);
$this->belongsTo('ParentSections', [ 'className' => 'Categories', 'foreignKey' => 'parent_id' ]);
$this->hasMany('Parkings', [ 'foreignKey' => 'category_id' ]); }
public function validationDefault(Validator $validator) { $validator ->integer('id') ->allowEmpty('id', 'create');
$validator ->scalar('name') ->maxLength('name', 255) ->requirePresence('name', 'create') ->notEmpty('name');
$validator ->boolean('visible') ->requirePresence('visible', 'create') ->notEmpty('visible');
return $validator; }
}
Model → Entity
<?phpnamespace App\Model\Entity;
use Cake\ORM\Entity;use Cake\ORM\Behavior\Translate\TranslateTrait;
class Category extends Entity { use TranslateTrait;
protected $_accessible = [ 'name' => true, 'visible' => true, 'parent_id' => true, 'lft' => true, 'rght' => true, 'created' => true, 'modified' => true, '_translations' => true ];}
Controller
class CategoriesController extends AppController {
public function index(){ $categories = $this->Categories->find('all');; $this->set(compact('categories'));
$descendants = $this->Categories->find('threaded', array( 'order' => array('lft ASC') // or array('id ASC') ));
$arrayCategories = $this->convertTreeToList($descendants, null);
//$descendants = $this->Categories->find('children', ['for' => 60])->find('threaded'); $this->set(compact('descendants')); $this->set(compact('arrayCategories')); }
public function view($id = null){ $category = $this->Categories->get($id); $this->set('category', $category); }
public function add() { $langs = $this->getServerLanguages(); $fieldsForm = $this->setFieldsToTranslate($langs, array('name')); $this->set('languageFields', $fieldsForm);
$category = $this->Categories->newEntity(); if ($this->request->is('post')) { $category = $this->Categories->patchEntity($category, $this->request->getData()); $category->name = $this->request->getData('_translations.en.name');
if ($this->Categories->save($category)) { $this->Flash->success(__('The category has been saved.'));
return $this->redirect(['action' => 'index']); } $this->Flash->error(__('The category could not be saved. Please, try again.')); }
$parentSections = $this->Categories->ParentSections->find('list'); $this->set(compact('parentSections')); $this->set(compact('category')); }
public function edit($id = null) {
$langs = $this->getServerLanguages(); $fieldsForm = $this->setFieldsToTranslate($langs, array('name')); $this->set('languageFields', $fieldsForm);
$category = $this->Categories->find('translations')->where(['Categories.id' => $id])->toArray(); $category = $category[0];
if ($this->request->is(['patch', 'post', 'put'])) { $category = $this->Categories->patchEntity($category, $this->request->getData());
if ($this->Categories->save($category)) { $this->Flash->success(__('The category has been saved.'));
return $this->redirect(['action' => 'index']); } $this->Flash->error(__('The category could not be saved. Please, try again.')); }
$parentSections = $this->Categories->ParentSections->find('list'); $this->set(compact('parentSections')); $this->set(compact('category')); }
public function delete($id = null){ $this->request->allowMethod(['post', 'delete']); $category = $this->Categories->get($id);
try { $this->Categories->delete($category);
$this->Flash->success(__('The category has been deleted.')); return $this->redirect(['action' => 'index']); } catch (\PDOException $e) { // The exact error message is $e->getMessage(); if($e->getCode() == '23503') { $this->Flash->error(__('The item you are trying to delete is associated with other records.')); return $this->redirect(['action' => 'index']); } else { $this->Flash->error(__('The category could not be deleted. Please, try again.')); $this->Flash->error($e->getMessage()); } } }
public function deleteAjax($id = null) { $this->autoRender = false; if ($this->request->is('ajax')) { $category = $this->Categories->get($this->request->data['id']); if ($this->Categories->delete($category)) { $complete['response'] = true; $this->response->type('json'); $this->response->body(json_encode($complete)); return $this->response; } } }
public function changeVisible(){ $this->autoRender = false;
if ($this->request->is('ajax')) { $category = $this->Categories->get($this->request->data['id']); if ($category) { $category->visible = $this->request->data['status']; if ($this->Categories->save($category)) { $complete['response'] = "ok"; $this->response->type('json'); $this->response->body(json_encode($complete)); return $this->response; } } } }
function convertTreeToList($categories, $pre_name = '|--> ') { $arrayCategories_tmp = array();
foreach ($categories as $category) { $category->name = $pre_name . $category->name;
$arrayCategories_tmp[] = $category;
if (!empty($category->children)) { $pre_name_tmp = str_replace('> ', '', $pre_name) . '|--> '; $arrayCategories_tmp = array_merge($arrayCategories_tmp, $this->convertTreeToList($category->children, $pre_name_tmp) ); } }
return $arrayCategories_tmp; }}
Template → Index
<?php use Cake\Routing\Router;?>
<section id="widget-grid" class=""> <div class="row"> <article class="col-xs-12 col-sm-12 col-md-12 col-lg-12"> <div class="jarviswidget jarviswidget-color-darken" id="wid-id-1" data-widget-colorbutton="false" data-widget-editbutton="false" data-widget-custombutton="false" data-widget-deletebutton="false"> <header> <span class="widget-icon"> <i class="fa fa-table"></i> </span> <h2><?= __('Categories', 'admin') ?></h2>
<div class="widget-toolbar"> <span class="widget-icon"> <a href="<?= $this->Url->build(['action' => 'add']);?>" style="color: white;"> <i class="fa fa-plus"></i> </a> </span> </div> </header> <div> <div class="jarviswidget-editbox"></div> <div class="widget-body no-padding"> <div class="table-responsive"> <table class="table table-bordered table-striped"> <thead> <tr> <th scope="col"><?= $this->Paginator->sort('name') ?></th> <th scope="col"><?= $this->Paginator->sort('visible') ?></th> <th scope="col" class="actions"><?= __('Actions', 'admin') ?></th> </tr> </thead> <tbody> <?php foreach ($arrayCategories as $category): ?> <tr> <td><?= h($category->name) ?></td> <td> <?php if($category->visible == 1): echo '<i class="fa fa-lg fa-fw fa-check" style="color:green" onclick="isVisible(this, ' . $category->id . ');return false;">'; else: echo '<i class="fa fa-lg fa-fw fa-times" style="color:red" onclick="isVisible(this, ' . $category->id . ');return false;">'; endif; ?> </td> <td class="actions"> <?= $this->Html->link( $this->Html->tag('i', '', array('class' => 'fa fa-lg fa-fw fa-eye', 'title' => __('View', 'admin'))), array('action' => 'view', $category->id), array('escape' => false) ) ?>
<?= $this->Html->link( $this->Html->tag('i', '', array('class' => 'fa fa-lg fa-fw fa-edit', 'title' => __('Edit', 'admin'))), array('action' => 'edit', $category->id), array('escape' => false) ) ?>
<a id="deleteButton" onclick="deleteAjax(this, <?= $category->id ?>)"><i class="fa fa-lg fa-fw fa-trash"></i></a> </td> </tr> <?php endforeach; ?> </tbody> </table> </div> </div> </div> </div> </article> </div></section>
<script type="text/javascript"> function deleteAjax(e,id) { $.SmartMessageBox({ title : "<?= __('Delete alert!', 'admin') ?>", content : "<?= __('Are you sure you want to delete this item?', 'admin') ?>", buttons : '[No][Yes]' }, function(ButtonPressed) { if (ButtonPressed === "Yes") { $.ajax({ url : '<?php echo Router::fullbaseUrl() . '/';?>admin/categories/deleteAjax', data : { id : id }, type : 'POST', dataType : 'json', success : function(data) { $.smallBox({ title : "<?= __('Success', 'admin') ?>", content : "<i class='fa fa-clock-o'></i> <i><?= __('Element removed correctly','admin') ?></i>", color : "#659265", iconSmall : "fa fa-check fa-2x fadeInRight animated", timeout : 6000 }); $(e).parent().parent().remove(); }, error : function(xhr, status) { $.smallBox({ title : "<?= __('Error', 'admin') ?>", content : "<i class='fa fa-clock-o'></i> <i><?= __('Error to connect the database', 'admin') ?></i>", color : "#C46A69", iconSmall : "fa fa-times fa-2x fadeInRight animated", timeout : 4000 }); } }); } if (ButtonPressed === "No") { // "NO" Actions } }); }
function isVisible(e, idcategory) { if($(e).hasClass("fa-check")){ visible = 0; } else { visible = 1; }
$.ajax({ url : '<?php echo Router::fullbaseUrl() . '/';?>categories/setVisible', data : { id : idcategory, visible : visible }, type : 'POST', dataType : 'json', success : function(data) { if (visible == 1) { $(e).attr('class', 'fa fa-lg fa-fw fa-check'); $(e).attr('style', 'color:green'); } else { $(e).attr('class', 'fa fa-lg fa-fw fa-times'); $(e).attr('style', 'color:red'); } }, error : function(xhr, status) { alert('Error to connect the database.'); } }); }</script>
Template → Form
<?php$this->loadHelper('Form', [ 'templates' => 'app_form']);
?>
<section id="widget-grid" class=""> <div class="row"> <article class="col-sm-12 col-md-12 col-lg-12"> <div class="jarviswidget jarviswidget-color-blueDark" id="wid-id-3" data-widget-colorbutton="false" data-widget-editbutton="false" data-widget-custombutton="false" data-widget-deletebutton="false"> <header> <span class="widget-icon"> <i class="fa fa-edit"></i> </span> <h2><?= __('Category', 'admin') ?> </h2> </header> <div> <div class="jarviswidget-editbox"> </div> <div class="widget-body no-padding"> <?= $this->Form->create($category, array('class' =>'smart-form')) ?>
<ul id="myTab1" class="nav nav-tabs bordered"> <?php foreach($languageFields as $languageField): ?> <li <?php if ($languageField === $languageFields[0]): ?>class="active" <?php endif; ?>> <a href="#<?= $languageField['locate'] ?>" data-toggle="tab" style="color: #2d2d2d !important"><?= $languageField['Lang_title'] ?></a> </li> <?php endforeach; ?> </ul> <div id="myTabContent1" class="tab-content padding-10"> <?php foreach($languageFields as $languageField): ?> <div <?php if ($languageField === $languageFields[0]): ?>class="tab-pane fade in active"<?php else:?>class="tab-pane fade"<?php endif; ?> id="<?= $languageField['locate'] ?>"> <fieldset> <section> <?= $this->Form->control($languageField['name'], ['placeholder' => __('Name','admin'), 'label' => false] ); ?> </section> </fieldset> </div> <?php endforeach; ?> </div>
<fieldset> <section> <?= $this->Form->control('parent_id', ['options' => $parentSections, 'empty' => 'No parent']); ?> </section> <section> <?= $this->Form->control('visible', ['type' => 'checkbox', 'label' => false, 'required' => false]); ?> </section> </fieldset> <footer> <?= $this->Form->button(__('Submit','admin'), array('class' => 'btn btn-primary') ) ?> <button type="button" class="btn btn-default" onclick="window.history.back();"> <?= __('Back','admin') ?> </button> </footer> <?= $this->Form->end() ?> </div> </div> </div> </article> </div></section>
Template → view
<?phpuse Cake\Routing\Router;?>
<section id="widget-grid" class=""> <div class="row"> <article class="col-xs-12 col-sm-12 col-md-12 col-lg-12"> <div class="jarviswidget jarviswidget-color-darken" id="wid-id-1" data-widget-colorbutton="false" data-widget-editbutton="false" data-widget-custombutton="false" data-widget-deletebutton="false"> <header> <span class="widget-icon"> <i class="fa fa-table"></i> </span> <h2><?= h($category->name) ?></h2>
<div class="widget-toolbar"> <span class="widget-icon"> <a href="<?= $this->Url->build(['action' => 'edit', $category->id]);?>" style="color: white;"> <i class="fa fa-edit"></i> </a> </span> </div> </header> <div> <div class="jarviswidget-editbox"></div> <div class="widget-body no-padding"> <div class="table-responsive"> <table class="table table-bordered table-striped"> <tr> <th scope="row"><?= __('Name', 'admin') ?></th> <td><?= h($category->name) ?></td> </tr> <tr> <th scope="row"><?= __('Created', 'admin') ?></th> <td><?= h($category->created) ?></td> </tr> <tr> <th scope="row"><?= __('Modified', 'admin') ?></th> <td><?= h($category->modified) ?></td> </tr> <tr> <th scope="row"><?= __('Visible', 'admin') ?></th> <td><?= $category->visible ? __('Yes', 'admin') : __('No', 'admin'); ?></td> </tr> </table> </div> </div> </div> </div> </article> </div></section>