How to use correctly group by in CakePHP3 - cakephp

I want to calculate the number of people in a room based on the model Reservation field Reservation.people (int).
Error:
Reservation not Associated in group
What am I doing wrong?
$hostel = $this->Hostel->get($id, [
'contain' => [
'Room' => [
'conditions' => [
'Room.status' => '0'
],
'sort' => [
'Room.number'
],
'Reservation' => [
'fields' => [
'reservation_room_id' => 'Reservation.room_id',
'sum' => 'SUM(Reservation.people)'
],
'conditions' => [
'Reservation.status' => '0'
],
'group' => [
'Reservation.room_id'
]
]
]
]
]);

You are getting this error because you have not defined association in your model.
Cakephp 2.x
Assuming Reservation has many to one relationship with Group, then you can define your association in below file like following
app/Model Reservation.php
class Reservation extends AppModel {
public $belongsTo = 'Group';
}
Cakephp 3.x
/src/Model/Table/ReservationsTable.php
class ReservationsTable extends Table
{
public function initialize(array $config)
{
$this->belongsTo('Groups');
}
}
Hope this will help!

Related

I'm getting a 404 error using Laminas Framework. Can anyone assist?

The error is:
A 404 error occurred
Page not found.
The requested URL could not be matched by routing.
No Exception available
I've registered my module and namespace with Composer and then ran Composer dump-autoload. My code is as follows:
module\Album\config\module.config.php
<?php
declare(strict_types=1);
namespace Album;
use Laminas\Router\Http\Segment;
use Laminas\ServiceManager\Factory\InvokableFactory;
return [
'router' => [
'routes' => [
'album' => [
'type' => Segment::class,
'options' => [
'route' => '/album[/:action[/:id]]',
'constraints' => [
'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
'id' => '[0-9]+',
],
'defaults' => [
'controller' => Controller\AlbumController::class,
'action' => 'index',
],
],
],
],
],
'controllers' => [
'factories' => [
Controller\AlbumController::class => InvokableFactory::class,
],
],
'view_manager' => [
'template_map' => [
'album/index' => __DIR__ . '/../view/album/album/index.phtml',
],
'template_path_stack' => [
'album' => __DIR__ . '/../view',
],
],
];
module\Album\src\Module.php
<?php
declare(strict_types=1);
namespace Album;
class Module
{
public function getConfig() : array
{
return include __DIR__ . '/../config/module.config.php';
}
}
module\Album\src\Controller\AlbumController.php
<?php
declare(strict_types=1);
namespace Album\Controller;
use Laminas\Mvc\Controller\AbstractActionController;
use Laminas\View\Model\ViewModel;
class AlbumController extends AbstractActionController
{
public function indexAction()
{
return new ViewModel();
}
}
module\Album\view\album\album\index.phtml
Index page displays here...
As you specified the root as
'route' => '/album[/:action[/:id]]',
The url should look like http://laminas.com/album which will route to the indexAction as you have defined that action as the default, but http://laminas.com/album/index would have the same effect.

Array to string conversion in Route

I'm imploding the Socialite driver from config\auth but getting the error called Array to string conversion
This is the route:
Route::get('redirect/{driver}', 'Auth\LoginController#redirectToProvider')
->name('login.provider')
->where('driver', implode('|', config('auth.socialite.drivers')));
These are the drivers on config.auth.socialite
'socialite' => [
'drivers' => [
'github' => [
'client_id' => env('GITHUB_KEY'),
'client_secret' => env('GITHUB_SECRET'),
'redirect' => env('GITHUB_REDIRECT_URI')
],
'google' => [
'client_id' => env('GOOGLE_CLIENT_ID'),
'client_secret' => env('GOOGLE_CLIENT_SECRET'),
'redirect' => env('GOOGLE_CALLBACK_URL'),
],
],
],```
You only want the keys listed under drivers, so try something like:
Route::get('redirect/{driver}', 'Auth\LoginController#redirectToProvider')
->name('login.provider')
->where('driver', implode('|', array_keys(config('auth.socialite.drivers'))));

Cakephp model virtualFields not working

I already have some virtual fields working on my application, but this one is busting my mind.
So I have the entity SubactivitySlots, with the following code:
protected $_virtual = [
'slots_text',
];
and
protected function _getSlotsText(){
return "test";
}
When I run the query:
debug($this->SubactivitySlots->find('all')->first());
It returns me the following structure (tried with both first and toArray()
object(App\Model\Entity\SubactivitySlot) {
'id' => (int) 1,
'name' => 'MAIN',
'description' => '-',
'activity_id' => (int) 1,
'subactivity_min' => (int) 1,
'subactivity_max' => (int) 1,
'position' => (int) 1,
'institution_id' => (int) 1,
'deleted' => (int) 0,
'[new]' => false,
'[accessible]' => [
'*' => true
],
'[dirty]' => [],
'[original]' => [],
'[virtual]' => [
(int) 0 => 'slots_text'
],
'[errors]' => [],
'[invalid]' => [],
'[repository]' => 'SubactivitySlots'
}
Any clue of what might be wrong? I'm spent a lot of time trying to discover and can't find out. The strangest thing is that i'm using virtual fields on another entities and it's working.
Thanks
If I'm not wrong cake does not debug virtual fields until 3.5.13.
In cake 3.4 the $_virtual property is used when "converting entities to arrays or JSON" (from here) but not in debug mode.
So even if you don't see them when you debug you should see them when uou convert the entity in JSON
Anyway this should have changed in 3.5.13 (see the blog here) so if you can upgrade the issue will be solved

Checkbox values in prestashop

I'm working with prestashop and try to get value from a form with checkbox using a HelperForm
SO what I had is :
$fields_form[0]['form']= [
'legend'=> [
'title'=> $this->l('Indexation')
] ,
'input'=>[
[
'type'=>'text',
'label'=> $this->l('Base(s) à indexer'),
'name'=>'options',
'size'=>20,
'required'=>true
]
],
'submit'=>[
'title' => $this->l('Save'),
'class' => 'btn btn-default pull-right'
]
];
and then
$helper = new HelperForm();
[...]
$helper->toolbar_btn = array(
'save' =>
array(
'desc' => $this->l('Save'),
'href' => AdminController::$currentIndex.'&configure='.$this->name.'&save'.$this->name.
'&token='.Tools::getAdminTokenLite('AdminModules'),
),
'back' => array(
'href' => AdminController::$currentIndex.'&token='.Tools::getAdminTokenLite('AdminModules'),
'desc' => $this->l('Back to list')
)
);
// Load current value
$helper->fields_value['options'] = Configuration::get('options');
return $helper->generateForm($fields_form);
and in my getContent I had :
$my_module_name = strval(Tools::getValue('options'));
return $my_module_name;
So until there I had no problem. I write 'test' in the text input and then 'test' is returned but I don't want a text input I want a checkbox input so I changed my form for :
$fields_form[0]['form']= [
'legend'=> [
'title'=> $this->l('Indexation')
] ,
'input'=>[
[
'type'=>'checkbox',
'label'=> $this->l('Base(s) à indexer'),
'name'=>'options',
'required'=>true,
'values'=>[
'query'=>$options,
'id'=>'id',
'name'=>'name'
]
]
],
'submit'=>[
'title' => $this->l('Save'),
'class' => 'btn btn-default pull-right'
]
];
and $options is :
$options = [
[
'id'=>1,
'name'=>'test'
],
[
'id'=>2,
'name'=>'test2'
]
];
and in my getContent(): return (Tools::getValue('options'));
But with that, nothing is displayed.
Also, if I do return sizeof(Tools::getValue('options)) It give me 1 no matter what I check with the checkbox
First you need to set the name of the field with []
$fields_form[0]['form']= [
'legend'=> [
'title'=> $this->l('Indexation')
] ,
'input'=>[
[
'type'=>'checkbox',
'label'=> $this->l('Base(s) à indexer'),
'name'=>'options[]',
'required'=>true,
'values'=>[
'query'=>$options,
'id'=>'id',
'name'=>'name'
]
]
],
'submit'=>[
'title' => $this->l('Save'),
'class' => 'btn btn-default pull-right'
]
];
Then, you options should have a value:
$options = [
[
'id'=>1,
'name'=>'test',
'val' => 1
],
[
'id'=>2,
'name'=>'test2',
'val' => 2
]
];
Then you can get the checked values with:
Tools::getValue('options')
Edit:
In 1.6 we have the admin tpl for the helper:
{foreach $input.values.query as $value}
{assign var=id_checkbox value=$input.name|cat:'_'|cat:$value[$input.values.id]}
<div class="checkbox{if isset($input.expand) && strtolower($input.expand.default) == 'show'} hidden{/if}">
{strip}
<label for="{$id_checkbox}">
<input type="checkbox" name="{$id_checkbox}" id="{$id_checkbox}" class="{if isset($input.class)}{$input.class}{/if}"{if isset($value.val)} value="{$value.val|escape:'html':'UTF-8'}"{/if}{if isset($fields_value[$id_checkbox]) && $fields_value[$id_checkbox]} checked="checked"{/if} />
{$value[$input.values.name]}
</label>
{/strip}
</div>
{/foreach}
So, to set the checkbox value to be returned we need to pass the val:
{if isset($value.val)} value="{$value.val|escape:'html':'UTF-8'}"{/if}
Also, to be checked or not when loading the page we pass the values to meet the criteria:
{if isset($fields_value[$id_checkbox]) && $fields_value[$id_checkbox]} checked="checked"{/if}

CakePHP Crud API Filtering Fields

I have written an API with the CakePHP v2.x framework. I am using the Friends of Cake Crud plugin. I need to hide sensitive data field by default for all replies, such as:
User.stripe_api_key
I have setup my component array as follows:
public $components = [
'RequestHandler',
'Crud.Crud' => [
'listeners' => [
'Api',
'ApiTransformation' => [
'changeNesting' => true,
'changeKeys' => false,
'changeTime' => true,
'castNumbers' => true,
],
'ApiFieldFilter' => [
'allowNoFilter' => true,
'blacklistFields' => ['User.stripe_api_key']
],
'ApiPagination'
]
]
];
This break my API though because my reply now returns 500 and:
"name": "Please specify which fields you would like to select",
According to the documentation this can be fixed with:
// Allow request without ?fields=
'allowNoFilter' => true,
Whether this value is set to true or false the reply is always 500 with the ApiFieldFilter enabled.
Any suggestions?
Thank you.

Resources