Production-grade rapid controller development with built in love for API and Search

Overview

Build Status Coverage Status Total Downloads Latest Stable Version

Installation

For CakePHP 4.x compatible version:

composer require friendsofcake/crud

For CakePHP 3.x compatible version:

composer require friendsofcake/crud:^5.0

For CakePHP 2.x compatible version:

composer require friendsofcake/crud:~3.0

Introduction

Crud was built to be scaffolding on steroids, and allow developers to have enough flexibility to use it for both rapid prototyping and production applications, even on the same code base -- saving you time.

  • Crud is very fast to install, a few minutes tops.

  • Crud is very flexible and has tons of configuration options.

  • Crud aims to stay out of your way, and if it happens to get in your way, you can change the undesired behavior very easily.

  • Crud relies heavily on CakePHP events and is possible to override, extend, or disable almost all of Crud's functionality either globally or for one specific action.

  • Usually, the basic code for controller CRUD actions are very simple and always looks the same. Crud will add the actions to your controller so you don't have to reimplement them over and over again.

  • Crud does not have the same limitations as CakePHP's own scaffolding, which is "my way or the highway." Crud allows you to hook into all stages of a request, only building the controller code needed specifically for your business logic, outsourcing all the heavy boilerplating to Crud.

  • Less boilerplate code means less code to maintain, and less code to spend time unit testing.

  • Crud allows you to use your own views, baked or hand-crafted, in addition to adding the code needed to fulfill your application logic, using events. It is by default compatible with CakePHP's baked views.

  • Crud also provides built in features for JSON and XML API for any action you have enabled through Crud, which eliminates maintaining both a HTML frontend and a JSON and/or XML interface for your applications -- saving you tons of time and having a leaner code base.

Bugs

If you happen to stumble upon a bug, please feel free to create a pull request with a fix (optionally with a test), and a description of the bug and how it was resolved.

You can also create an issue with a description to raise awareness of the bug.

Features

If you have a good idea for a Crud feature, please join us on IRC/Slack in the #friendsofcake channel and let's discuss it (this is not a support channel). Pull requests are always more than welcome.

Support / Questions

You can use any of CakePHP's support forums/channels for any support or questions.

Comments
  • JsonApiListener

    JsonApiListener

    Refs #310. This is a working prototype of the JsonApi listener. It uses neomerx/json-api, a lot of inspiration from josbeir/cakephp-json-api and currently supports index, view, add, edit, delete and error responses.

    The reason I'm putting it out here is that I believe this would be a most valuable listener to Crud and CakePHP as it would make our framework instantly compatible with a lot of tools and frameworks out there like Ember Data. Given the fact that version 1.1 of the jsonapi spec is coming this might also be the right time.

    GENERAL

    • [x] warn user if suggested composer package is not installed
    • [X] require the application/vnd.api+json Accept request header (by adding detector)
    • [X] require the application/vnd.api+json Content-Type request header when posting data
    • [x] support all php predefined json constants
    • [x] remove _id fields from response body as described here
    • [x] add custom route with support for (belongsTo) relationship self links
    • [X] ~extend custom route to support (hasMany) relationship self links~
    • [X] generate self::SHOW_SELF relationship-self-belongsTo-link: /countries/1/relationships/currency
    • [X] generate self::SHOW_SELF relationship-self-hasMany-link: /cultures?country_id=1
    • [X] ApiPaginationListener support
    • [X] ApiQueryLogListener support
    • [X] add tests
    • [X] prevent redirects after delete, add, etc. (by implementing beforeRedirect stop event)
    • [x] document

    PRESENTING RESOURCES (READ)

    • [X] automatically generate json api for single entity using dynamic schema
    • [X] automatically generate json api for entity collections using dynamic schema
    • [X] allow overrides by creating manual schema(s)
    • [X] support resource-less responses (empty body or meta node only)
    • [X] respond with application/vnd.api+json Content-Type response header
    • [X] set viewVars using Crud listener configuration options
    • [x] properly add top-level query node to 200 responses (respecting jsonOptions config option)
    • [x] implement neomerx exception renderer for default errors

    CREATING RESOURCES (CREATE/UPDATE)

    • [x] create resources without relationships
    • [x] create resources with relationships (belongsTo only as per the spec)
    • [x] update resources without relationships
    • [x] update resource along with belongsTo relationships
    • [X] ~update resource along with hasMany relationships (unsure if the spec supports this atm)~
    • [x] add DocumentValidator to ensure incoming request data structure respects the jsonapi crud specification
    • [x] properly decode incoming jsonapi data to cake compatible format
    • [x] implement neomerx exception renderer for (both entity and document) validation errors
    • [x] enforce using PATCH instead of PUT as described here
    • [x] display correct body after successful add action (with and without relationships)
    • [x] fix DocumentValidator bug: correctly posted hasMany relationship data is now being flagged invalid (claiming type and id nodes are missing when they actually exist).

    DELETING RESOURCES

    • [x] respond with 204 status code, empty body and no redirect after successful delete

    NICE TO HAVES:

    • [X] make JSON_PRETTY_PRINT optional for debug mode
    • [ ] support (JSON API spec) optional related links
    • [ ] configurable links in error responses (now hardcoded)
    • [ ] respect jsonOptions config option when generating exceptions. Will probably require a custom ErrorController to be placed in the app by end-user
    • [ ] support status codes 415 and 406 as described here
    • [ ] automatic success member a-la ApiListener inside top-level meta member as config option
    • [ ] ability to respond with 200 status code and meta (only) body after successful delete (as described here)
    • [ ] ~on success send optional Location header with link to created resource as described here.~ Removed from prototype because it caused a CORS redirect error
    • [ ] jsonp?

    MISC:

    • [x] solved: why are NeoMarx options not respected (e.g. show-self-top-level)
    • [x] solved: fix missing SELF link in included member ?

    ADDITIONAL READING:

    opened by bravo-kernel 37
  • Replace the translations listener with configuring messages in actions.

    Replace the translations listener with configuring messages in actions.

    Such a lot of code changes for what is essentially rewriting one method.

    This makes it possible to define the flash messages on the action objects, instead of in one unweildy listener.

    Will likely need some tweaking.

    opened by AD7six 27
  • Added more data to the scaffolded views

    Added more data to the scaffolded views

    • Keeps BC with regular ScaffoldView class
    • Adds special bits of data for usage on scaffolded views
    • Updated basic ScaffoldListenerTest class
    • Added nicer, scaffolded views
    • Added bootstrap-based styling

    Still some work to do.

    http://cl.ly/image/1o1l3p1O0Y40 http://cl.ly/image/3m3e051t313Y http://cl.ly/image/1a3z3P2V2l0d http://cl.ly/image/3D0G3q2C2o3L http://cl.ly/image/2L19433c3m0Y

    opened by josegonzalez 26
  • Adds listener to make API output consistent with other popular APIs.

    Adds listener to make API output consistent with other popular APIs.

    Why?

    Currently the API output is pretty similar to CakePHP array. This isn't a problem when it's a private API and you are the only one using it. However to the outside world it looks a bit weird and is unpredictable compared to APIs from Twitter, Google, GitHub, etc.

    What does it do?

    This listener does three things:

    • Nests data of associated data properly under the primary record.
    • Converts camel cased model names to singular/plural keys.
    • Casts values from strings to their proper datatypes.

    There are options for each of these features which you can disable at any time. This means you can only use it for the casts or the nesting as well. You can leave the keys intact for example.

    Example

    GET https://api.example.com/users.json
    

    Normal output:

    {
        "success": true,
        "data": [{
            "User": {
                "id": "15",
                "username": "Phally"
            },
            "Profile": {
                "id": "51",
                "twitter": "@Phally"
            }
        }]
    }
    

    New output:

    {
        "success": true,
        "data": [{
            "id": 15,
            "username": "Phally",
            "profile": {
                "id": 51,
                "twitter": "@Phally"
            }
        }]
    }
    
    opened by Phally 25
  • Custom Method class not found

    Custom Method class not found

    I'm trying to add a custom action, following these instructions

    http://crud.readthedocs.io/en/latest/actions/custom.html#using-custom-named-controller-actions

    I have the following:

    public function initialize() {
            
            parent::initialize();
            
            $this->loadComponent('Crud.Crud', [
                'actions' => [
                    'test' => ['className' => 'App\Controller\test']
                ],
                'listeners' => ['Crud.Api'],             
            ],'RequestHandler'
            );
            
            $this->Crud->config(['listeners.api.exceptionRenderer' => 'App\Error\ExceptionRenderer']);
            $this->Crud->addListener('relatedModels', 'Crud.RelatedModels');
    
        }
        
        public function beforeFilter(Event $event){
            parent::beforeFilter($event);
            $this->Crud->addListener('Crud.Api');
        }
    
        public function test() {         
            $this->Crud->execute();
        }
    

    When I call test.json I get the following:

    message: "Class 'App\Controller\TestAction' not found",

    Also are the documents correct, it says to use: \App\Crud\Action\ but the top of my controller use the namespace: namespace App\Controller. I tried both but the result is the same - missing class.

    What am I doing wrong?

    question documentation 
    opened by spacebiscuit 22
  • Add json api query support and include support

    Add json api query support and include support

    This adds support to the json api for parsing query parameters. Included as part of this is ability to pass the include query parameter to conditionally load relationships.

    JSONAPI 
    opened by dakota 21
  • relatedModels in Crud.View?

    relatedModels in Crud.View?

    AppController includes:

    $this->loadComponent('Crud.Crud', [
        'actions' => [
            'Crud.Index',
            'Crud.Add',
            'Crud.Edit',
            'Crud.View',
            'Crud.Delete'
        ]
    ]);
    $this->Crud->addListener('relatedModels', 'Crud.RelatedModels');
    

    I have a belongsToMany relationship that is correctly handled by Crud.Add & Crud.Edit (i.e., the related data is displayed in a multi-select list and the selected items are saved to the DB).

    Now I just want to view the related data in the view. The baked view template is looking for the data, but Crud.View is not querying for it. This seems to be the (odd) default behavior according to doc ...

    So now I am setting my AppController to:

    $this->loadComponent('Crud.Crud', [
        'actions' => [
            'Crud.Index',
            'Crud.Add',
            'Crud.Edit',
            'View' => [
                'className' => 'Crud.View',
                'relatedModels' => true
            ],
            'Crud.Delete'
        ]
    ]);
    $this->Crud->addListener('relatedModels', 'Crud.RelatedModels');
    

    But still no related data.

    This seems pretty hard vs. just baking the controller ... Or?

    So if src/Model/Table/ContactsTable.php =

    class ContactsTable extends Table
    {
        public function initialize(array $config)
        {
            $this->belongsToMany('Categories');
        }
    }
    

    then the baked controller's view action obviously includes the contain:

    public function view($id = null)
    {
        $contact = $this->Contacts->get($id, [
            'contain' => ['Categories']
        ]);
        ...
    

    Should Crud.View know to do the same?

    opened by thumbtech 21
  • [RFC] Search Listener

    [RFC] Search Listener

    This listener is a thin wrapper around the CakeDC/Search plugin

    By default it just automates all the loading of PrgComponent and SearchableBehavior as well as applying any filters that can be found in $this->request->query to the paginated result set

    It also offers a scope feature, where you can define the query key/value your self - and thus make some more human-readable and shorter URLs

    In the example below you can access /admin/feeds/?scope=active, /admin/feeds/?scope=sample and /admin/feeds?scope=active_sample

    scope() also have a 3rd argument, which is the filterArgs that is defined in the model. This allows for ad-hoc / permission based filterArgs if the developer wish to do so - either in a listener, or in a beforeFilter

    I'm gonna implement tests once we decide on the features and structure of the listener

    <?php
    
    App::uses('AppController', 'Controller');
    
    /**
     * Feeds Controller
     *
     * @property Feed $Feed
     */
    class FeedsController extends AppController {
    
        public function admin_index() {
            $this->Crud->listener('Scoped')
                ->scope('active', ['active' => 1])
                ->scope('sample', ['site_id' => 62]])
                ->scope('active_sample', ['active' => 1, 'deal_site_id' => 62]);
    
            return $this->Crud->executeAction();
        }
    }
    
    opened by jippi 18
  • Crud Scaffold View

    Crud Scaffold View

    Getting closer. At this point, I have the following things to update:

    • [x] Add filtering to the index action. http://cl.ly/image/0p1h3s002M3O
    • [x] Allow turning off the automatic ordering of fields. This is a nice feature to have by default. Slows the page down slightly but worth it.
    • [x] Remove __field__ etc. from form options
    • [x] Add view for delete action. Will make some things much easier - as then we can just redirect to the action instead of having some special form logic. The GET to a delete will show a page, a DELETE or POST of a DELETE will actually delete. The page will contain a form to confirm deletion. http://cl.ly/image/3f1w011v3N3e
    • [x] Add the option of removing related actions, but keeping the current model actions on the side. http://cl.ly/image/1S1g1z031x3v
    • [x] Use crud namespace for translations
    • [x] Ensure headings are the same across all views.
    • [x] Custom layout that removes the sql_dump element when the debug_kit plugin is enabled
    • [x] Allow specifying a logo path (or just text) from configuration. Default to Admin. http://cl.ly/image/0K2n2A0S3B0C
    • [x] Use redirect_url and persist that url until we are redirected to that url
    • [x] Add the option of making a global menu. http://cl.ly/image/1d2C1C2J2e2i
    • [x] Make the selects and booleans inline-block. Looks much nicer. http://cl.ly/image/142e3b0O1a0m
    • [x] Add multiple save options to forms. http://cl.ly/image/0b0B3V1J0e03
    • [x] Fix tests. Should be easier to test now, but still not fixed. Anyone want to do this for me? http://cl.ly/image/160c3Z110332
    • [x] Specify per-record actions vs model-level
    • [x] Link to all actions for the current controller where appropriate

    Future work

    • [ ] Restyle the admin using Twitter Bootstrap 3.0. I'll try to use mixins to override the current cake styles, as opposed to re-doing all the admin css/customizing the helper.
    • [ ] Remove record-specific actions from the sidebar. These should always go within the main view. Kind of weird to hunt for the delete button in a sidebar when you have the data in a main view.
    • [ ] Minimize search filters by default. Smoothly expand via js.
    • [ ] Choose jquery plugins for random integrations (datetime picker, date range, sliders, etc.). These should be turned on via form options.
    • [ ] Ajax validation. Not sure how that would work with SecurityComponent. @ADmad ?
    • [ ] Fix up the view template. Never was a fan of the definition lists.
    • [ ] Edit related (hasMany/hasOne) models. Add related models.

    That's my workload. Maybe some of it doesn't belong in here/no one wants. Comments?

    enhancement 
    opened by josegonzalez 16
  • Error Installing on Cake 3.0

    Error Installing on Cake 3.0

    I followed the book exactly to install CRUD 4.0 on cake 3.0 but keep getting the following error: Fatal error: Trait 'Crud\Controller\ControllerTrait' not found

    question 
    opened by akeiper 15
  • RFC, Beefing up the docs

    RFC, Beefing up the docs

    I'd really like to contribute to the documentation. I think there is lots of room for improvement. However I am a little worried as I don't feel I know the plugin well enough to write accurate documentation.

    I'm happy to make an effort and get the ball rolling. What is the suggested approach for this? I'm not a fan of readthedocs for a number of reasons, so what's the best way to submit my contributions?

    My initial thought was to just fork and start working on markdown files in a /docs folder, but this seems to be where all the readthedocs stuff is. Then I thought it might be productive to create a github pages branch, but that seems to already exist as well.

    If I can get some guidance and support, I'm happy write up the documentation to the best of my knowledge. I can mark parts which I'd like to cover, but need input on and hopefully someone can chip in on those parts.

    opened by davidyell 14
  • Make redirect variable name configureable

    Make redirect variable name configureable

    This patch makes redirect variable name configurable via:

    $action->setConfig('redirectVar', 'new_value');
    

    Default value of 'redirect_url' for backward compatibility

    opened by asgraf 1
  • Move beforePaginate() of RelatedModelsListener in a separate listener.

    Move beforePaginate() of RelatedModelsListener in a separate listener.

    Containing related model in the query is a very different operation than setting view vars for select options for related models.

    Also CrudView's ViewListener contains associated models in it's beforePaginate() and beforeFind(), so having a separate listener in Crud for containing would allow better control.

    opened by ADmad 0
  • Document useModel() Method.

    Document useModel() Method.

    I am using:

    CakePHP version: 3.10.4 Crud version 5.5.1

    I was attempting to use the CRUD plugin on a table from within in a plugin. I had to manually search the code until I found the useModel() method. I knew that I had to specify that my table was in a plugin, however, since this method wasn't mentioned I spent quite some time searching for it. Would be nice to mention useModel() in the docs.

    opened by TerryKern 0
  • Added example for extra key in ApiListener Action

    Added example for extra key in ApiListener Action

    I thought the documentation could get a bit improved here with an example of how exactly add an extra key to response, as up for today I never really figured it out and even then it took me some trying ;)

    opened by gringlas 1
  • IndexAction ignores `belongsToMany` association conditions

    IndexAction ignores `belongsToMany` association conditions

    I’m using friendsofcake/crud I have a pivot table EnquiryContacts which joins Enquiries, Roles and People tables. The EnquiriesTable has a belongsToMany association:

    $this->belongsToMany('Clients', ['through' => 'EnquiryContacts', 'className' => 'People', 'conditions' => ['role_id' => 3], 'foreignKey' => 'enquiry_id', 'targetForeignKey' => 'person_id']);
    

    And the PeopleTable has the reverse association:

    $this->belongsToMany('ClientEnquiries', ['through' => 'EnquiryContacts', 'className' => 'Enquiries', 'conditions' => ['role_id' => 3], 'foreignKey' => 'person_id', 'targetForeignKey' => 'enquiry_id']);
    

    But results returned by IndexAction will include records with any role_id, instead of just those within the conditions.

    Is this expected behaviour or a bug? If expected, how should I go about ensuring a response that takes the conditions of the association into account?

    opened by geoidesic 0
  • Impoved docs build

    Impoved docs build

    I've improved the docs build a bit, so that it's up-to-date and easier to contribute to it:

    1. Old Docker config and docs gave some issues, so set Docker to the latest Debian release.

    2. Added docs build and checks to Travis CI.

    3. Upgraded the docs build to Python 3.

    4. Added reStructuredText lint using RSTcheck.

    5. Fixed an issue RSTcheck flagged. See first paragraph: https://crud.readthedocs.io/en/latest/unit-testing.html

    6. Added Browser Sync config for easier editing.

      Does an automated build and an automated browser refresh when saving a file:

      Better resolution: https://youtu.be/NnocyVp-KHc

      Watch on YouTube

    opened by Phally 4
Releases(6.1.1)
YCOM Impersonate. Login as selected YCOM user 🧙‍♂️in frontend.

YCOM Impersonate Login as selected YCOM user in frontend. Features: Backend users with admin rights or YCOM[] rights, can be automatically logged in v

Friends Of REDAXO 17 Sep 12, 2022
Silverstripe-searchable - Adds to the default Silverstripe search by adding a custom results controller and allowing properly adding custom data objects and custom fields for searching

SilverStripe Searchable Module UPDATE - Full Text Search This module now uses Full Text Support for MySQL/MariaDB databases in version 3.* Adds more c

ilateral 13 Apr 14, 2022
CRUD Build a system to insert student name information, grade the class name, and edit and delete this information

CRUD Build a system to insert student name information, grade the class name, and edit and delete this information

Sajjad 2 Aug 14, 2022
A cross-language remote procedure call(RPC) framework for rapid development of high performance distributed services.

Motan Overview Motan is a cross-language remote procedure call(RPC) framework for rapid development of high performance distributed services. Related

Weibo R&D Open Source Projects 5.8k Dec 20, 2022
A dockerized magento 2 community environment ready for development or production.

Painless Magento 2 & 1 A dockerized magento 2 community environment ready for development or production. It supports magento 1.9.x for development Ins

Cocoa Web Studio 10 Apr 23, 2022
Open Source Spotify playlist creator. Made with LOVE on PHP

MotherS_Playlist Description This is an open source application that acts like a playlist manager for Spotify, for now the user can create randomize o

Pedro Caires 2 May 28, 2022
search non profitable charity or organization through api search

Non Profile Charity Search Search non profitable organization or get the details of an organization Installation Require the package using composer: c

Touhidur Rahman 5 Jan 20, 2022
A PHP library to integrate with eWAY's Rapid Payment API.

A PHP library to integrate with eWAY's Rapid Payment API.

null 0 Jul 15, 2022
Doogle is a search engine and web crawler which can search indexed websites and images

Doogle Doogle is a search engine and web crawler which can search indexed websites and images, and then use keywords to be searched later. Written pri

Zepher Ashe 9 Jan 1, 2023
Nova Search is an open source search engine developed by the Artado Project.

Loli Search Loli Search açık kaynak kodlu bir arama motorudur ve yalnızca kendi sonuçlarını değil, diğer arama motorlarının sonuçlarını da göstermekte

Artado Project 10 Jul 22, 2022
This is a port of the original WireGuard UI bits as implemented by Netgate in pfSense 2.5.0 to a package suitable for rapid iteration and more frequent updating on future releases of pfSense.

This is a port of the original WireGuard*** UI bits as implemented by Netgate in pfSense 2.5.0 to a package suitable for sideloading and more frequent updating on future releases of pfSense. This also includes some improvments such as a proper status page (found under Status / WireGuard Status) and improved assigned interface handling.

R. Christian McDonald 195 Dec 23, 2022
PHP implementation of Rapid Automatic Keyword Exraction algorithm (RAKE) for extracting multi-word phrases from text

PHP implementation of Rapid Automatic Keyword Exraction algorithm (RAKE) for extracting multi-word phrases from text.

Assisted Mindfulness 7 Oct 19, 2022
Rubix Server is a library for bringing your trained Rubix ML models into production.

Rubix Server is a library for bringing your trained Rubix ML models into production. Inference servers are stand-alone services that run on your private or public network and wrap your trained estimator in an API that can be queried locally or over the network in real-time using standard protocols. In addition, the library provides async-compatible client implementations for making queries to the server from your PHP applications.

Rubix 50 Aug 15, 2022
Contracts for Rule Doc Generator. Useful for production code with minimum dependencies.

Rule Doc Generator Contracts Contracts for Rule Doc Generator. Useful for production code with minimum dependencies. Install composer require symplify

null 19 Dec 22, 2022
PaaS template based on production template using platform.sh

Shopware for Platform.sh This template builds Shopware on Platform.sh using Composer. To get started on Platform.sh, please visit https://docs.platfor

Shopware 9 Oct 12, 2022
Production ready scalable Magento setup utilizing the docker

Magento docker image Requirements This docker image expects 2 other linked containers to work . Mysqldb or Mariadb linked as 'db' Memcached linked as

Paim pozhil 49 Jun 21, 2021
🧙‍♂️ Simple Wizard Controller for Laravel.

Laravel Wizards Simple Wizard Controller for Laravel. If you need a more sophisticated solution, then have a look at Laravel Aracanist. Installation I

Marvin Rabe 29 Apr 25, 2022
Actions: controller + auth + validation in one class

Actions: controller + auth + validation in one class This package provides only one class: an Action class that extends the FormRequest class we all k

edatta 2 Dec 15, 2022
Smile ElasticSuite - Magento 2 merchandising and search engine built on ElasticSearch

News ⚠️ Magento versions compatibility : Due to several changes in Magento 2.4.0, we cannot ensure compatibility between ElasticSuite <2.10 and Magent

Smile - Open Source Solutions 724 Dec 30, 2022