CAKEPHP 3: Like condion special character paginate - cakephp

I'm having trouble finding likes with special characters as follows
in the database i have a record with the name Toan"123
now, in cakephp 3 i use query ORM
$sqlSub = $sysLogTable
->find('all', [
'fields' => array('id' ,'name')
'conditions' => array("name LIKE" => "%Toan"%")
])
->toArray();
but I don't get Toan"123. How to get Toan"123 with sql above.
Please help me, I'm stuck

Related

cakephp joins vs containable

i am developing with cakephp (2.4.7) and i am using the containable option.
I have a few find statements with about 15 Tables/Models inside the containable array and my query log shows about 60-100 queries.
Should i use joins instead of containable due to better performance?
My site requires high performance standard.
And is it possible to join automatically based on the linking models like containable, or do i have to set up the joins manually like:
Example:
$this->Message->find('all', array(
'joins' => array(
array(
'table' => 'users',
'alias' => 'UserJoin',
'type' => 'INNER',
'conditions' => array(
'UserJoin.id = Message.from'
)
)
),
'conditions' => array(
'Message.to' => 4
),
'fields' => array('UserJoin.*', 'Message.*'),
'order' => 'Message.datetime DESC'
));
Guide me the correct way to achieve my objective.
Contain takes a lot of system resourses to product a data from tables since it is make a lot of queries and apply Hash::nest() function to each of them.
But with joins you will get a lot of dublicated data, and you will need to extract data from it by yourself. Not the best solution, huh.
I don't know which one will be better for you, but the best way to get most performance results is to get use index in your tables and cache.

How can I read a Post(by id) and their Comments who has only status > 0?

How can I read a Post(by id) and their Comments who has only status > 0?
Here is my code:
$conditions= array(
'conditions' => array('Post.id' => $id, 'Comment.status >' => '0'),
);
$post = $this->Post->find('first',$conditions);
And here is the error:
Unknown column 'Comment.status' in 'where clause'
My Post Model:
public $hasMany = array(
'Comment' => array(
'className' => 'Comment',
'foreignKey' => 'post_id',
),
)
Your conditions dont make much sense.
You cannot combine both in a single query right away.
The relation is 1:N.
If you want to find all posts to comments which are status > 0:
You need to do it the other way around.
Always query the model that has the belongsTo relations. This way it will be a single query.
If you had debugged your query you would have seen that there are many queries run - especially one for the Post and then a few extra ones for the comments.
So:
$this->Post->Comment->find()
with
contain => array('Post')
If that gives you multiple results due to multiple Comments you can use 'group' or Distinct.
Alternatively you could make a subquery which would be a little bit slower probably.
If you want to find a specific post and then comments with status > 0
Use first a normal find for it without the second condition. And add contain with that condition to get all related data. Don't combine it in both, since it won't be a single query in this case anyway.
$options = array(
'conditions' => array('Post.id' => $id)
'contain' => array('Comment' => array('conditions' => array(...)))
);
$this->Post->find('first', $options);
See the documentation.
Alternativly you can make two separate find calls (same exact result).
Hello,
You also need to give relation to the "Comment" Model -> belongsTo "Post"
Thanks & Regards,
Hasmukh

CakePHP won't fetch more than 800 rows

I'm trying to write a weekly report for a system. Part of the report will display information about translators that is not stored in the database - that is, for each translator I have to pull their DB record, run some logic, and for the ones that fail the logic I remove them from the array that gets passed to the view.
I would not anticipate having more than a couple dozen records left in the view, but there are just over 1,000 in the database. There is no way to limit the number getting pulled out of the database as the criteria I'm using is not stored there.
I'm using the following query to pull all rows. However, unless I add a 'limit' clause and limit it to 800 rows (I experimented with this), it won't actually return any results. If I debug the result array, it comes up blank. I have debugging mode on, but no errors are given at all, and there's nothing in the Cake logs or IIS logs either.
I have tried introducing an offset and limit and looping through in chunks but I have the same issue when I try to combine it all together again. After this find query, the memory usage is around 6MB, with the PHP limit set much higher (128MB I think).
Any ideas? I am stumped and pulling my hair out!
$translators = $this->Translator->find('all', array(
'conditions' => array(
'OR' => array(
array('Translator.translators_status_id' => 1),
array('Translator.translators_status_id' => 2)
)
),
'fields' => array(
'Translator.id',
'Translator.translators_status_id',
'Translator.first_name',
'Translator.last_name',
'Translator.agency_name',
'NativeLanguage.name',
'Country.printable_name'
),
'joins' => array(
array(
'table' => 'languages',
'alias' => 'NativeLanguage',
'type' => 'INNER',
'conditions' => array(
'Translator.language_id = NativeLanguage.id'
)
),
array(
'table' => 'countries',
'alias' => 'Country',
'type' => 'INNER',
'conditions' => array(
'NativeLanguage.country_id = Country.id'
)
)
)
)
);
EDIT:
The solution I landed with was to only pull 500 rows at a time. Then on each batch of 500, I performed the logic test and removed rows from the array. Finally, I stitched each reduced batch back together.
I guess you are just running out of memory.
There is (or was?) quite an interesting discussion about that here:
http://www.mail-archive.com/cake-php#googlegroups.com/msg50610.html
This was nothing to do with memory after all. In CakePHP 2.2 (and possibly higher), the debug() function does not play nicely with certain UTF-8 characters if your database collation is not set to UTF-8. Running debug() on an array with any values containing these characters just ends up with "blank" output from the debugger. I assume that in my example above, I wasn't running into any problematic characters until the 800+nth row.
Now our DB collation is set to UTF-8 and CakePHP is set to connect to MySQL as UTF-8 and this problem has gone.

cakephp contain filtering by parent model value

I have these relations:
Attendance belongs to Employee
Schedule belongs to Employee
This find() works just fine to get all Attendance records in a date range.
$data = $this->Attendance->find('all', array(
'contain' => array(
'Employee' => array(
'Schedule' => array(
'conditions' => array('sche_status' => 1),
'order' => 'sche_valid DESC',
'limit' => 1
))
),
'conditions' => $conditions,
'order' => array('employee_id', 'att_date')
)
);
However, this Schedule condition
'conditions' => array('sche_status' => 1),
gets the "current" Schedule. Problem is when Employee has more than one Schedule in the date range.
In order to get the relevant Schedule for it's parent Attendance record, I need to also
condition on Attendance.att_date
Tried
'conditions' => array('sche_status' => 1, 'ho_valid <=' => Attendance.att_date)
and
'conditions' => array('sche_status' => 1, 'ho_valid <=' => $this->Attendance.att_date)
How can I reference Attendance.att_date from the contan Schedule conditions? Is that possible?
My current datasets are pretty clean and my find() is dry, wouldn't want to make a mess here.
Any help greatly appreciated.
When you use contain(), it does individual queries. In your example, it will actually do three queries individually that then get combined by CakePHP into the returned data array.
So, you cannot use fields from a different model to condition against a contained model.
Your best bet is to either query the field first, then use it's value in this find, or use joins(), which makes all the results return from a single query instead of three separate queries.
Side note - it appears you're building this query in a Controller - following the MVC structure, best practice is to keep ALL queries in your Model, not your Controller - then just call the Model's method (which has the find()) from the Controller to retrieve the results.

Saving non-associated data in CakePHP

I am writing an installer, and as such I need to save multiple types of data in different tables, even when not associated. Ideally I woud like to take care of this all at once. Here is a brief of what I have so far.
Here is my cake array in preparation for saving said data.
$initialData = array(
array( 'Option' => array( 'name' => 'version', 'value' => '1.0.0', )),
array( 'Option' => array( 'name' => 'non-version', 'value' => '1.0.2', )),
array( 'User' => array( 'username' => 'skyler', 'password' => 'hi', )),
);
And I use the following to try and save it.
$this->Option->saveMany($initialData)
Which only saves the Option rows, not the User rows. Thoughts?
NOTE: This is NOT associated data. Options and Users are not associated, but need to be saved at the same time.
The $this->Option->saveMany will work because you are saving multiple records for a single table. However, because the User is not associated to the Option, it does not know what to do with the data. You will need to call $this->User->save($initialData).
If you expect to have multiple user records, you can call $this->User->saveMany($initialData).
Be sure not to forget to call $this->User->create().
I usually just ship an SQL script with my packages which creates and populates the database tables.
See Multiple SQL query not executing in Cakephp for an example of how to read and execute the file in CakePHP.

Resources