Wiki

Clone wiki

suitcms / old-doc

How to Use SuitCMS

This section is about to use SuitCMS, keep in your mind that first we understand to use it. After you can use Suitcms, you can understand all of the syntax later.

A. Directory Structures

this is common directory that we will use.

  1. app/core/Suitcms - Root of Suitcms.
  2. Suitcms/Support/routes.php - Used to define new routes for your module.
  3. Suitcms/Controller - Used to define your module controller.
  4. Suitcms/Model - Used to define your module Model.
  5. Suitcms/Form -Used to define your module Form.
  6. app/view/admins - Used to define your module view.

B. Build a Simple Module

First, we will build a module called packages that contain simple database:

Buid the Database

  1. Go to app/database/migration and edit the create_packges_table file.
  2. Create table packages contains title column php artisan migrate:make create_packages_table --create=packages
        Schema::create('packages', function(Blueprint $table)
            {
                $table->increments('id');
                $table->string('title');
                $table->dateTime('updated_at')->nullable();
                $table->dateTime('created_at')->nullable();
            });
    

3 . php artisan migrate

Define the Routes

Go to app/core/Suitcms/Support/routes.php and define the routes:

    \Route::resource('packages', 'PackageController'); // Package Controller will be defined later

Define the Controller

create files named PackageController.php in Suitcms/Controller and add code some code:

<?php
    namespace Suitcms\Controller;

    use Suitcms\Model\Package as Model; // Package Model will be defined later
    use Suitcms\Form\PackageForm as Form; // Package Form will be defined later

    class PackageController extends ResourceController
    {
        public function __construct(Model $model, Form $form)
        {
            parent::__construct($model, $form);
            \View::share('navPackage', true); // share variable navPackage to indicate the active page is Package
        }
    }

Define the Model

Create files named Package in Suitcms/Model and add code some code:

<?php

    namespace Suitcms\Model;

    use Suitcms\Log\LoggableInterface;

    class Package extends BaseModel implements LoggableInterface
    {

        // define your table name

        protected $table = 'packages';


        // define the fillable column

        protected $fillable = array(
            'title'
        );

        // show data column 'title' in index view

        public function listById()
        {
            return $this->lists('title', 'id');
        }

        // log name - usualy Page - [Model name]

        public function getLogModuleName()
        {
            return 'Page Package';
        }


        // default, don't change methods below!

        public function getLogName()
        {
            return $this->title;
        }

        public function getUrlAttribute()
        {

            return url($this->parentPrefixUrl().$this->getUrlKey());
        }

        protected function parentPrefixUrl()
        {
            $prefix = '';

            $parent = $this->parent;
            if ($parent !== null) {
                $prefix = $parent->parentPrefixUrl(). $parent->getUrlKey();
            }

            return $prefix.'/';
        }
    }

Define the Form

Create files named PackageForm in Suitcms/Form and add code some code:

<?php

    namespace Suitcms\Form;

    // validation

    class PackageForm extends BaseForm
    {
        protected function rules()
        {
            $rules = ['title' => 'required'];
            return $rules;
        }
    }

Define the View

Now create folder app/view/admins/packages consist of four views: index.blade.php create.blade.php edit.blade.php form.blade.php

you can copy the files from other modules and just modify it.

    // modify the index

    <a href="{{ suitRoute('packages.create') }}"....
    ...
    <a href="{{ suitRoute('packages.edit',....
    <a href="{{ suitRoute('packages.destroy',....

    // modify create and edit

    @extends('admins.packages.form')
    ...
    // modify form
    ...
    {{ Form::suitText('title', 'Title') }}
    ...

Finalization, enable the view in sidebar

    // app/view/admins/_includes/sidebar.blade.php
    ...
    <li class="{{ ($active = isset($navPackage))?'active':'' }}">
        <a href="{{ suitRoute('packages.index') }}">
            <i class="icon-grid"></i>
            <span class="title">Packages</span>
            @if ($active)
                <span class="selected"></span>
            @endif
        </a>
    </li>
    ...

Congratulation, you have created simple module !!!

C. Add 1-N Relationship

Now we will add column category_id in packages table. This column is a foreign key to table category that have already exists.

Update the table

php artisan migrate:make add_category_id_to_package_table --table=packages

    ...
    public function up()
    {
        Schema::table('packages', function(Blueprint $table)
        {
            $table->integer('category_id')->unsigned();
            $table->foreign('category_id')
                  ->references('id')->on('categories')
                  ->onDelete('cascade');
        });
    }

    public function down()
    {
        Schema::table('packages', function(Blueprint $table)
        {
            $table->dropColumn('category_id');
        });
    }
    ...
php artisan migrate

Update the Model

    ...
    protected $fillable = array(
        'title',
        'category_id' // add category_id to fillable
    );


    // add function to get package categories

    public function categories()
    {
        return $this->belongsToMany('Suitcms\Model\Category', 'categories');
    }
    ...

Update the Controller

    ...
    protected function formData()
    {
        parent::formData();
        \View::share('categories', $this->categoryList()); //list of categories that will show in select form
    }


    // get categories

    protected function categoryList()
    {
        $categories =  $this->model->categories()->getRelated();

        return $categories->listById();
    }
}

Update the Form

    $rules = [
            'title' => 'required',
            'category_id' => 'required' // add this
            ];

Update the View

    ...
    {{ Form::suitSelect('category_id', 'Category', $categories) }}
    ...

Done! You have created 1-N relationship !!!

D. Add M-N Relationship

Now we will try M-N relationship between table packages and categories. According to this, we must create new table called package_category

Create the table

php artisan migrate:make create_packageCategory _table --create=package_category

    ...
    public function up()
    {
        Schema::create('package_category', function(Blueprint $table)
        {
            $table->increments('id');
            $table->integer('package_id')->unsigned()->index();
            $table->integer('category_id')->unsigned()->index();

            $table->foreign('package_id')
                  ->references('id')->on('packages')
                  ->onDelete('cascade');
            $table->foreign('category_id')
                  ->references('id')->on('categories')
                  ->onDelete('cascade');

            $table->dateTime('updated_at')->nullable();
            $table->dateTime('created_at')->nullable();
        });
    }

    ...
php artisan migrate

Update the Model

    ...
    public function manyCategories()
    {
        return $this->belongsToMany('Suitcms\Model\Category', 'package_category');
    }
    ...

Update the Controller

    ...
    protected function formData()
    {
        parent::formData();
        \View::share('categories', $this->categoryList());
        \View::share('manyCategories', $this->manyCategoryList());
    }

    ...

    protected function manyCategoryList()
    {
        $categories =  $this->model->manyCategories()->getRelated();

        return $categories->listById();
    }

    protected function doSave()
    {
        parent::doSave();
        if (!empty($this->form->input('manyCategories'))) {
            $this->model->manyCategories()->sync($this->form->input('manyCategories'));
        }
    }
}

Update the Form

    protected $manyCategoryList = [];

    // validation

    protected function rules()
    {
        $rules = [
            'title' => 'required',
            'category_id' => 'required',
            'manyCategories' => 'array'
            ];

        return $rules;
    }

    public function setManyCategoryList(array $value)
    {
        $this->manyCategoryList = $value;
    }

Update the View

    ...
    <!-- parameter - array, name, data, , id for value-->
    {{ Form::suitMultiSelect('manyCategories[]', 'manyCategories', $manyCategories, null, $model->manyCategories->lists('id'))}}
    ...

C. Add 1-N Relationship

Now we will add column category_id in packages table. This column is a foreign key to table category that have already exists.

Update the table

php artisan migrate:make add_category_id_to_package_table --table=packages

    ...
    public function up()
    {
        Schema::table('packages', function(Blueprint $table)
        {
            $table->integer('category_id')->unsigned();
            $table->foreign('category_id')
                  ->references('id')->on('categories')
                  ->onDelete('cascade');
        });
    }

    public function down()
    {
        Schema::table('packages', function(Blueprint $table)
        {
            $table->dropColumn('category_id');
        });
    }
    ...
php artisan migrate

Update the Model

    ...
    protected $fillable = array(
        'title',
        'category_id' // add category_id to fillable
    );


    // add function to get package categories

    public function categories()
    {
        return $this->belongsToMany('Suitcms\Model\Category', 'categories');
    }
    ...

Update the Controller

    ...
    protected function formData()
    {
        parent::formData();
        \View::share('categories', $this->categoryList()); //list of categories that will show in select form
    }


    // get categories

    protected function categoryList()
    {
        $categories =  $this->model->categories()->getRelated();

        return $categories->listById();
    }
}

Update the Form

    $rules = [
            'title' => 'required',
            'category_id' => 'required' // add this
            ];

Update the View

    ...
    {{ Form::suitSelect('category_id', 'Category', $categories) }}
    ...

Done! You have created 1-N relationship !!!

E. Add Upload Image

Add column

php artisan migrate:make add_column_image_name_to_package_table --table=packages

    ...
    public function up()
    {
        Schema::table('packages', function(Blueprint $table)
        {
            $table->string('image_name')->nullable();
        });
    }

    ...

    public function down()
    {
        Schema::table('packages', function(Blueprint $table)
        {
            $table->dropColumn('image_name');
        });
    }

    ...
php artisan migrate

Update the Model

    ...
    protected $fillable = array(
        'title',
        'category_id',
        'image_name'
    );
    ...

Update the Controller

    ...
    public static $image_path = '/assets/admin/packages/';
    ...
    protected function doSave()
    {
        if(!$this->model->exists) {
            $this->savePackage();
        } else {
            $this->updatePackage();
        }
        if (!empty($this->form->input('manyCategories'))) {
            $this->model->manyCategories()->sync($this->form->input('manyCategories'));
        }
    }

    public function doDelete() {
        $this->deleteImage($this->model);
        parent::doDelete();
    }

    private function savePackage() {
        parent::doSave();
        if (!empty($this->form->input('categories'))) {
            $this->model->categories()->sync($this->form->input('categories'));
        }

        if(\Input::hasFile('image_name')) {
            $this->saveImage($this->model, \Input::file('image_name'));
        }
    }

    private function updatePackage() {
        $previousModel = $this->model->getOriginal();
        $previousImagePath = public_path().static::$image_path.$previousModel['id'].'/'.$previousModel['image_name'];
        if(\File::exists($previousImagePath)) {
            \File::delete($previousImagePath);
        }

        $this->savePackage();
    }

    private static function saveImage($package, $image)
    {
        $package->image_name = $image->getClientOriginalName();
        $path = public_path().static::$image_path.$package->id;
        if(!\File::exists($path)) {
            \File::makeDirectory($path);
        }
        $image->move($path, $package->image_name);
        $package->save();
    }

    private static function deleteImage($package)
    {
        if($package->image_name != null) {
            $directoryPath =  public_path().static::$image_path.$package->id;
            $imagePath = $directoryPath.'/'.$package->image_name;
            \File::delete($imagePath);
            \File::deleteDirectory($directoryPath);
        }
    }
    ...
}

Update the Form

    $rules = [
            'title' => 'required',
            'category_id' => 'required',
            'manyCategories' => 'array',
            'image_name' => ''
            ];

Update the View

    ...
    Form::suitModel($model,array('route'=>($model->exists?[suitRouteName("$routePrefix.update"),$model->getUrlKey()]:suitRouteName("$routePrefix.store")), 'method'=>($model->exists?'PUT':'POST'), 'files' => true)) }}
    {{ Form::suitFileInput('image_name', 'Image Name') }}
    ...

don't forget to create directory packages first in asset/admin

E. Add Roxy File Manager in CKEditor

/public/assets/admin/global/plugins/ckeditor/config.js

    var roxyFileman = "/assets/admin/global/plugins/roxy-fileman/index.html";
CKEDITOR.editorConfig = function( config ) {
    config.filebrowserBrowseUrl = roxyFileman;
    config.filebrowserImageBrowseUrl =roxyFileman+'?type=image';
    config.removeDialogTabs = 'link:upload;image:upload';

};

Updated