Cakephp pagination with more than one order condition - mysql

Currently I have a table called as 'Users'. With columns like
Id, name, image, is_active, etc, etc, created, modified
I am setting up a pagination, where it will display all Users one by one, on click of next button(in the view)
here not all Users will have images. So my pagination order will be: to show users who have images first. Followed by Users who don't have images.
So far I have this
$this->paginate = array(
'limit' => 1,
'conditions' => array(
'User.is_active' => 0
),
'order' => array(
'User.image' => 'DESC'
),
'group' => array(
'User.id'
)
);
What I want is now, the view to FIRST display a random User, who has image, every time the page refreshes OR on the first load of the page. Followed by other Users who have images ,and then followed by Users who don't have images.
this query works fine in phpmyadmin sql panel. But I am not sure how do I write a cakephp paginate query for it
select * User order by image<>' ' desc,rand()
If you think I am missing any more data, please ask. I'll write it in comments

you can look at this answer SQL how to make null values come last when sorting ascending and try to change it with CakePHP conditions.

In your model you can set. I believe this works for the pagination order as well.
public $order = array(
'ISNULL(Users.image) ASC',
'RAND() * User.id'
);
But this makes all the users randomized. I don't know how you may do it to show only in the first record a random user with the order field. I would suggest using a custom function in which you may choose a random row and put it in the top of the array.

Related

CakePHP 3.x Saving new record but also new associated record

So I'm developing a system where a user can create a new account and upload a profile photo. I'm using two models: User for the account, Photo for the photos.
The users table has a foreign key on the field photoId that references to photos.id. The photos table has a userId field that has a foreign key referencing users.id. So there is a recursive relationship between User and Photo. Reason for this: when a Photo is created, we want to be able to see which User uploaded the Photo. A User has one Photo as his profile image.
So it's Photo hasOne User and User hasOne Photo. They are also configured this way in their Table classes.
Now, when a new User is saved, we want to also save a new Photo. Photo needs the id of the newly created User in order to save, but the User needs the id of the newly created Photo.
My question: what is the best method to save this? Should we allow User.photoId to be null, so that we can first save the User, then save the Photo, and then update the User with the correct Photo.id, or can CakePHP3 do some magic where it does all of this linking back and forth for you?
Data that comes from the form:
[
'username' => 'John Doe',
'mail' => 'john#example.org',
'password' => 'whatever',
'photo' => [
'name' => 'myImage.jpg',
'type' => 'image/jpeg',
'tmp_name' => '/private/var/tmp/phpN3dVmL',
'error' => (int) 0,
'size' => (int) 40171
]
]
Make Things Simple !
Why you need hasOne relations for both table ?
It looks like you are making simple thing so complected.Let's talk about that:
You have two tables users and photos that's fine.
At the moment each user has one photo that's fine as well.
Just imagine one day user might have multiple photo, then ?
Then still no worries, everything would be good because you have photos table already.
So what kind of relations do you actually need here ?
Just like mentioned above, user has one photo, That's why relation should be:
user hasOne photo and obviously photo belongsTo user.
And you need nothing more than that.
Just for example
Fields on Users table
id
name
email
address
has_photo // eg:if has_photo = 1 user has uploaded photo,such field is not compulsary
password...etc
Fields on Photos table
id
user_id // foreign key of users table
name
size
Relations
// UsersTable.php
$this->hasOne('Photos', [
'foreignKey' => 'user_id'
]);
// PhotosTable.php
$this->belongsTo('Users', [
'foreignKey' => 'user_id',
'joinType' => 'INNER'
]);
Don't be confuse on that photos need user_id..users table never need photo_id.Because users table already associated with photos table. And if A hasOne B then B obviously belongs to A.That's the simple logic.
Don't hesitate to see the documentation ( Associations
) to get more information on relations..This is really important things for database management.
or can CakePHP3 do some magic where it does all of this linking back and forth for you?
Yes! As long as your associations are setup correctly Cake will take care of the rest. So the best method is to pass your data array into newEntity or patchEntity and make sure that all passed fields are accessible in you entity.
Saving hasOne relationships
Entities and mass assignment

Can I make two seemingly unrealated associations between two tables?

I am developing a resume app and have created a table called areas using the CakePHP Tree Behaviour. In this table, I have a bunch of countries and cities.
The original purpose of this table was to allow users to specify which areas they are interested in working in on their resume. This is pretty straightforward and I have created a HABTM relationship between users and areas to deal with this.
However, the next thing I need to do is allow users to specify where they are from. Of course, I could create a new table, identical to areas and call it something different, but this seems a bit wasteful and inefficient.
So, I am wondering if it is actually possible to have two totally different associations between the users table and the areas table?
In other words, the users table would have-and-belong-to-many areas (for the purpose of users specifying all of the areas they are interested in working in in the world) but it would also have-one area (for the purpose of users specifying which country they are from).
I can't begin to imagine how to go about properly setting up the models according to CakePHP convention -- or whether it is even a good idea to attempt this -- so I would appreciate any pointers anyone can give.
I am also happy to hear people's opinions even if the answer is not CakePHP-specific because this is more of a database question than anything else.
You can specify any association you want.
for example in your user Model:
/**
* #see Model::$hasAndBelongsToMany
*/
public $hasAndBelongsToMany = array(
'Area' => array(
'className' => 'Area',
'joinTable' => 'user_areas',
'foreignKey' => 'user_id',
'associationForeignKey' => 'area_id',
),
);
/**
* #see Model::$hasOne
*/
public $belongsTo = array(
'Farea' => array(
'className' => 'Area',
'foreignKey' => 'farea_id',
),
);

Kohana ORM store count in many-to-many relationship

I'm building a application using Kohana 3.2 and Kohana ORM.
The application has systems. Systems contain components. A system may contain multiple components, but also multiple components of the same type. E.g. System_A may have 10 Component_Y and 3 Component_Z
So instead of just having two belongs_to fields in my pivot table I also want to store the count.
If I just use a has-many-through I won't be able to access the count. Without ORM I'd just join the count onto the component in SQL, because the count is unique for the System + Component combination and so I can access the count for the component when I visit the object in the context of a certain system.
How best to go about this in Kohana ORM?
I solved it partially this way:
protected $_has_many = array(
'omvormer' => array(
'model' => 'omvormer',
'through' => 'systeemomvormer'
),
'systeemomvormer' => array(
'model' => 'systeemomvormer',
)
);
I've added the pivot tabel systeemomvormer separately to systeem.
I can now do this:
$so = ORM::factory("systeemomvormer");
$so->where('systeem_id', '=', $systeem_id);
$so->where('omvormer_id', '=', $omvormer_id);
$result = $so->find();
$result->aantal = $omvormer_count;
But it really still only is a partial solution, because I'm not able to update() the result. Kohana says that the result is not loaded. However that's outside the scope of this question and I'll open a new question for that.
This was also helpfull:
http://forum.kohanaframework.org/discussion/7247/kohana-3-orm-save-for-update-a-many-to-many/p1
To store more data in a junction table than just the two keys, you need to create a model for it.
So,
system _has_many system_component
component _has_many system_component
system_component _belongs_to component
system_component _belongs_to system
However, you may not need to store the count if you do it this way. Instead, you can do the following:
$system->components->count_all();
Then, to access them:
foreach($system->components->find_all() as $component)
echo $component->component->name;

CakePHP Displaying Field Names via Two Associations

I apologize for the confusing title, I was a little stumped as to how to word my question.
I am new to CakePHP, but am following along through the cookbook/tutorials nicely, however I have come up against something which I cannot find an answer to.
My structure is as follows:
'Invoices' hasMany 'InvoiceHistory'
'InvoiceHistory' belongsTo 'InvoiceHistoryDeliveryStatus'
Whereby, an invoice can have multiple invoice histories, and each history contains a delivery status id, which links to a name.
On the Invoice view (index.ctp) I am displaying a list of all invoices but wish to display the Most Recent Delivery Status Name (InvoiceHistory contains a date field so it can be sorted) - thereby displaying the 'current Delivery Status'.
When I do:
$this->set('invoices', $this->Invoice->find('all'));
It does not go deep enough in what it returns to provide me with Delivery Status Names, nor have I deduced a way of only returning the most recent Invoice History within my result. I know how to do this manually with a MYSQL query but I figured that is probably just plain wrong.
What is the correct way of going about this while following CakePHP conventions?
Use Containable
$this->Invoice->Behaviors->attach('Containable');
$this->set('invoices', $this->Invoice->find('all', array(
'contain' => array(
'InvoiceHistory' => array(
'InvoiceHistoryDeliveryStatus'
)
)
));
From what I can tell, I think you should check out the Containable behavior.

Wordpress - How do I output the last query used by query_posts?

I am attempting to grab all posts for a specific day (ie: today), however for some reason it is only returning the one.
$wp_posts = query_posts(array(
'cat' => 4,
'post_status' => array('any', 'publish', 'future', 'inherit', 'revision', 'pending'),
'year' => '2011',
'monthnum' => '10',
'day' => '25',
'order_by' => 'post_date',
'order' => 'ASC'
));
This should post all the posts for today under a category, but whatever reason it only outputs 1 post and I do not know why.
At first I thought it might be a permalink issue, but I removed the permalinks and its still only returning the one post?
On my localhost the code works fine and outputs all the content required for a specific day.
Additionally, I have checked the database and all the posts for the day are there and appear to be in schedule or posted status.
So there is no reason why the query_posts should be returning just 1 item.
I want to output the last query used by query_posts to investigate what is causing the problem.
How do I verbosely output the last query as used by query_posts?
Thanks.
Edit.
I will accept an answer that converts the above to a verbose SQL query which I can run to see what is going on
Take a look at http://codex.wordpress.org/Editing_wp-config.php#Save_queries_for_analysis (please make sure you take note of the warning to not do this on a production site).
The solution is that you probably need to set the posts_per_page value in your arguments array to -1.
I figured out what the problem was.
On http://codex.wordpress.org/Custom_Queries it seems to imply that a post_limit has a default.
I successfully outputted the entire object using a blank page and combining WP_Query with my posts array posted above.
In it I found a response with a limit of 0,1
I'm not sure why it put this in, or why it only affected my live site.
But this seems to correspond with the limit I noted in the Custom_Queries code.
In my file, I put this:
add_filter('post_limits', 'gloss_limits' );
function gloss_limits( )
{
return "";
}
As per the Custom_Queries URL.
And it removed the limit and I finally got to output everything from that day.
I've accepted Jorbin's answer as the 'Save queries for analysis' is a specific answer to my query.
the last query is always stored in $wpdb->last_query
and for post queries as well in $wp_query->request