0
votes

I have an application in CakePHP 3.5.13. The application is connected to a legacy database - that is to say it has not been written according to Cake's naming conventions.

I have baked the application which has generated some Table and Entity classes.

Part of the application allows the user to perform a search. I'm wanting to use the Form Helper but am unsure how to name/configure things:

The template file where the search form lives has 11 text inputs. Each of these relates to data stored in the database. For brevity I'll consider the first 3 fields. These are associated with the Table classes:

  • CAS Number - related to CasTable
  • EC Number - related to EcsTable
  • Substance Name - related to SubstancesTable

When opening the form tag I have done the following:

<?php echo $this->Form->create(null, [
'url' => ['controller' => 'Front', 'action' => 'search'] ]); ?>

The reason I have passed null as the first parameter is because I don't know whether I'm supposed to use the instance of an Entity (as mentioned in the docs), but wasn't sure which one, since there are 11 inputs all of which are associated with different Table classes. So I believe null to be correct here - Please can someone clarify this?

I'm also unsure how to name my inputs. For example the input searching for "CAS Number" needs to do a search on the database field cas.value. So would I name the input like this?

echo $this->Form->control('cas.value' ... );

I want to be able to validate each field according to rules that would be in the appropriate models. Because there are 11 different fields, and the form is not acting as either an "add" (SQL INSERT) or "edit" (SQL UPDATE) function, I cannot follow the Cake documentation to understand how I'm supposed to code this.

In summary what I'm trying to do is construct a HTML form - using Cake's Form Helper syntax - with 11 fields all of which are associated with appropriate models. I want to be able to validate the fields as per rules of those models. How can I do this? I have done research into it but cannot see any examples that do this - most focus on inserting/updating data. I also had a look at Modeless Forms but don't think that's right because in this case I do have models for the search data.

At the moment I have simply written the form as vanilla HTML and can access the data posted to FrontController::search() through $this->request->data(). Whilst this works I believe this is a bad idea since I'd have to somehow run validation methods, and it may cause problems re-populating the form, or using the ORM later. I may be wrong here but am looking for a solution which uses Cake conventions, particularly focusing on correct use of the Form Helper in this type of situation.

1
did you try using cake naming convention for your controls as explained here? It works even if your DB naming does not follows cake standard. You should see your controls validated according to each table rule. Remember you can create different validation sets to use in different situations (create, update, search...) I also suggest using FriendsOfCake/search pluginarilia
see also herearilia
I have named the form controls according to the docs, for example <?php echo $this->Form->control('ecs.value', ['label' => 'EC Number']); ?>. I don't really understand where to put the validation function or how to run it when the form is submitted to my controller. The docs - book.cakephp.org/3.0/en/core-libraries/validation.html - seem to be dealing with inserting/updating data and I am not doing that. I appreciate you sending the link to the plugin but it's way too complicated already even without adding on more things to read through.Andy
the validation rules go in the table. Then - in the controller - when you post your data you can patch an entity even if you don't save it. See here. Also the search plugin iss meant to simplify your job. Expecially when you have so many fields to search...arilia

1 Answers

1
votes

I don't actually see why you have to validate the search (I think that if one of the search inputs for some reason is not ok then the query will simply return zero records) but I guess you have your reasons so here is how to do it. Anyway this works even for saving entities so:

Use naming Conventions

First of all use g cake naming convention for your controls as explained here and here

It works even if your DB naming does not follows cake standard.

Create validation rules

Then in each of your table crete the validations set. You can create different validation for differents uses (save, update, search) (see here). In your case you want to create a set for the search.

So in your tables (in every table!) you can create a method named validationSearch

public function validationSearch($validator)
{
    $validator
        ->add('title', 'notEmpty', [
            'rule' => 'notEmpty',
            'message' => __('You need to provide a title'),
        ]);
    return $validator;
}

Patch the entity

then in you FrontController you can do

$this->loadModel('Substances');
$substance = $this->Substances->newEntity(
    $this->request->getData(),
    [
        'validate' => 'search', // tells cake to use validateSearch
                                // for Substances Table
        'associated' => [
            'Cas' => [
                'validate' => 'search', // you want to use validateSearch
                                        // even for this table
            ],
            'Ecs'=> [
                'validate' => 'search', // and for this table, too
            ],
            // list of other related tables here
            // you can nest the array if you have
            // nested relationships
        ]
    ]
);

this will create an entity containing your data but above all it will check for validation issues and store the errors in the $substance entity.

$this->set('substance', $substance );

the above will pass your newly created entity to the form

Create the form

and finally in the view

<?php echo $this->Form->create($substance , [ /*... */ ]); ?>

So the form knows about the entity, the validation rules to apply and the validation errors to show

Create the controls

Suppose you have a "main" table, meaning that all the other tables are somehow related to this. Let's say it is Substances. So follow the conventions.

<?= $this->Form->control('name', ['label' => 'Substance name') ?> 
//                        ^ No need to prepend the table here
<?= $this->Form->control('cas.number', ['label' => 'Cas number') ?>
<?= $this->Form->control('ecs.number', ['label' => 'Ecs number') ?>

Use a plugin

And consider using using FriendsOfCake/search plugin. With so many fields to check it will simplify your life