Using order by FIELD in CakePHP - mysql

I'm trying to implement custom sort order into CakePHP 2 application, using the following code:
var $paginate = array(
'Project' => array(
'conditions' => array('Project.deleted' => 0),
'order' => array(
'Project.pinned' => 'desc',
'FIELD(Project.status, 1, 3, 4, 0, 2) DESC'
'Project.date_start' => 'asc',
'Project.name' => 'asc',
),
),
);
But, for some reason FIELD(Project.status, 1, 3, 4, 0, 2) DESC is ignored by Cake. Can you help me to make it work?

I made it work by making changes in /lib/Cake/Controller/Component/PaginatorComponent.php
I just found out how to do this and I know it is not perfect since it does not validate if the statement is correct but i think it's a good start for someone who got this issue.
In the function validateSort I added the last elseif for the case it is an ORDER BY FIELD. The problem is that the $order[$alias.'.'.$field] = $value can't work with FIELD since it works differently than most other ORDER BY clause.
foreach ($options['order'] as $key => $value) {
$field = $key;
$alias = $object->alias;
if (strpos($key, '.') !== false) {
list($alias, $field) = explode('.', $key);
}
if ($object->hasField($field)) {
$order[$alias . '.' . $field] = $value;
} elseif ($object->hasField($key, true)) {
$order[$field] = $value;
} elseif (isset($object->{$alias}) && $object->{$alias}->hasField($field, true)) {
$order[$alias . '.' . $field] = $value;
} elseif (strpos($alias, 'FIELD')==0){
$order[$key]=$value;
}
}

Remove array from order , It work in my case after removing array
var $paginate = array(
'Project' => array(
'conditions' => array('Project.deleted' => 0),
'order' =>
'Project.pinned' => 'desc',
'FIELD(Project.status, 1, 3, 4, 0, 2) DESC'
'Project.date_start' => 'asc',
'Project.name' => 'asc',
),
);

Related

How to Get WooCommerce Product Name with WP_Query?

I am trying to use this code on "Wp All Import". If there is a product name in the database, that product should be omitted, but the code will not work as is. What do I need to do for the code to work?
add_filter('wp_all_import_is_post_to_create', 'create_only_if_unique_custom_field', 10, 3);
function create_only_if_unique_custom_field( $continue_import, $data, $import_id ) {
// Only run for import ID 1.
if ( $import_id == 33 || $import_id == 34 ) {
// The custom field to check.
$key_to_look_up = "post_title";
// The value to check where 'num' is the element name.
$value_to_look_up = $data['name'];
// Prepare the WP_Query arguments
$args = array (
// Set the post type being imported.
'post_type' => array( 'post' ),
// Check our custom field for our value.
'meta_query' => array(array(
'key' => $key_to_look_up,
'value' => $value_to_look_up,
)),
);
// Run the query and do not create post if custom field value is duplicated.
$query = new WP_Query( $args );
return !($query->have_posts());
} else {
// Take no action if a different import ID is running.
return $continue_import;
}
}
You can do like this.
<?php
$params = array('posts_per_page' => 5);
$wc_query = new WP_Query($params);
?>
<?php if ($wc_query->have_posts()) : ?>
<?php while ($wc_query->have_posts()) :
$wc_query->the_post(); ?>
<?php the_title(); ?>
<?php endwhile; ?>
<?php wp_reset_postdata();?>
<?php else: ?>
<p>
<?php _e( 'No Products' ); ?>
</p>
<?php endif; ?>
There are some ways to show the different types of Woocommerce product names with WP_Query.
<?php
//Pulling WooCommerce Products instead of WordPress Posts, Use this param
$params = array(
'posts_per_page' => 5,
'post_type' => 'product'
);
//Displaying products of a given price range, use this param
$params = array(
'posts_per_page' => 100,
'post_type' => array('product', 'product_variation'),
'meta_query' => array(
'relation' => 'OR',
array(
'key' => '_price',
'value' => 5,
'compare' => '<=',
'type' => 'NUMERIC'
),
array(
'key' => '_sales_price',
'value' => 5,
'compare' => '<=',
'type' => 'NUMERIC'
)
)
);
//Displaying available products only, use this param
$params = array(
'posts_per_page' => 5,
'post_type' => array('product', 'product_variation'),
'meta_query' => array(
array(
'key' => '_price',
'value' => 5,
'compare' => '<',
'type' => 'NUMERIC'
),
array(
'key' => '_stock_status',
'value' => 'instock'
)
)
);
$wc_query = new WP_Query($params);
if ($wc_query->have_posts()) :
while ($wc_query->have_posts()) :
$wc_query->the_post();
the_title();
endwhile;
endif;
Also will help you the article https://www.gavick.com/blog/wp_query-woocommerce-products
Thank you
This variable controls the title.
// Xml file column name
$value = = $data['product_title'];
// Get wpdb product title
$posts = get_posts([
'post_type' => 'product',
'title' => $value,
]);

WP query retrieve the src of the attached image

I'm encoding in JSON a bunch of data from a WP Query:
$args = array(
'posts_per_page' => 20,
'post_type' => 'post',
'category' => 6,
'meta_key' => 'custom_total_hits',
'tag' => 'indie-pop',
'orderby' => 'meta_value_num',
'order' => 'DESC',
'date_query' => array(
'after' => date('Y-m-d', strtotime('-40 days'))
)
);
$query = new WP_Query( $args );
$posts = $query->get_posts();
foreach( $posts as $post ) {
$output[] = array(
'id' => $post->ID,
'title' => $post->post_title,
'count' => $post->custom_total_hits,
'soundcloud_url' => $post->soundcloud_song,
'soundcloud_id' => $post->soundcloud_ids,
'link' => get_permalink($post),
);
}
echo json_encode($output);
I would like to display in my JSON a key corrisponding to the src of the medium size of the attached image. If I use 'images' => get_attached_media('image', $post->ID) it retrives an array of multiple data which I can not access since I don't know the ID of the attached image when I process the data of my JSON. How can I do to retrieve a first level key - value where the value is the src of the attached image?
get_post_thumbnail_id : Get post thumbnail ID
wp_get_attachment_url : Get attachment URL by attachment id
'images' => parse_url( wp_get_attachment_url( get_post_thumbnail_id( $post->ID ) ) );
Would you please try above code?
Try this solution:
$images = array();
$post_thumbnail_id = get_post_thumbnail_id( $post->ID );
foreach (get_intermediate_image_sizes() as $size) {
$images[$size] = wp_get_attachment_image_src($post_thumbnail_id, $size);
}
//end
'images' => $images // type_of_size => image_url

Save an object in wordpress database

it is possibe to save an object in prefix_options in wordpress database like this one:
$arr_params = array( 'cat' => $display_category, 'product' => $single_post_ID );
Thanks
edit:
after make some changes, the code can't add an new array in exsisting array in the database:
$item= array(
'name' => $name ,
'prename' => $prename
);
print_r($item);
$options = get_option( 'options' );
if (empty($options['items'])) {
$options['items']=array();
add_option( 'options', $options );
$options = get_option( 'options' );
$options['items'] = array_push($options['items'], "$item");
update_option( 'options', $options );
}
else{
$options = get_option( 'options' );
$options['items'] = array_push($options['items'], "$item");
update_option( 'options', $options );
}
yes you can,
$arr_params = array( 'cat' => $display_category, 'product' => $single_post_ID );
if( get_option("_arr_params") === false ) {
add_option("_arr_params", $arr_params);
}
else {
// holds : array( 'cat' => $display_category, 'product' => $single_post_ID );
$my_param = get_option("_arr_params");
}
According to Edit Part: array_push() on works to add one or more elements not the array, you can use array_merge() in place of it, or second option is i already used in below codes.
$options['wphyper_orders'][] = $order_detail;
helpful link : get_option()

Adding comments to columns in codeigniter migrations

I am writing a lot of migration scripts for the database for my application. I would like to add comments for the columns so that others can easily recognize the column's content. One option is to write normal SQL query and add the comment. But is there a way I can add these comments inside the Migration scipt?
$this->dbforge->add_field(array(
'post_id' => array(
'type' => 'INT',
'constraint' => 11,
'unsigned' => true,
'auto_increment' => true,
'comment' => 'Unique post id'
),
'user_id' => array(
'type' => 'INT',
'constraint' => 11,
'unsigned' => true,
),
'group_id' => array(
'type' => 'INT',
'constraint' => 11,
'unsigned' => true,
),
'source' => array(
'type' => 'VARCHAR',
'constraint' => 20
),
'data' => array(
'type' => 'TEXT',
),
'created' => array(
'type' => 'INT',
'constraint' => 11,
'unsigned' => true,
),
'updated' => array(
'type' => 'INT',
'constraint' => 11,
'unsigned' => true,
),
'status' => array(
'type' => 'INT',
'constraint' => 1,
'unsigned' => true,
)
));
This is the basic code that I have written. May have some syntax error. But I just copy pasted it.
Can anyone please help.
CodeIgniter added this ability with version 3.0. You can add comments using the 'comment' key:
'first_name' => [
'type' => 'VARCHAR',
'constraint' => 45,
'null' => false,
'comment' => 'Put the field comment here',
]
Looking at the CodeIgniter core, specifically system/database/drivers/mysql/mysql_forge.php, it looks like the COMMENT field isn't supported.
For reference, here is the function that parses the fields array out:
function _process_fields($fields)
{
$current_field_count = 0;
$sql = '';
foreach ($fields as $field=>$attributes)
{
// Numeric field names aren't allowed in databases, so if the key is
// numeric, we know it was assigned by PHP and the developer manually
// entered the field information, so we'll simply add it to the list
if (is_numeric($field))
{
$sql .= "\n\t$attributes";
}
else
{
$attributes = array_change_key_case($attributes, CASE_UPPER);
$sql .= "\n\t".$this->db->_protect_identifiers($field);
if (array_key_exists('NAME', $attributes))
{
$sql .= ' '.$this->db->_protect_identifiers($attributes['NAME']).' ';
}
if (array_key_exists('TYPE', $attributes))
{
$sql .= ' '.$attributes['TYPE'];
if (array_key_exists('CONSTRAINT', $attributes))
{
switch ($attributes['TYPE'])
{
case 'decimal':
case 'float':
case 'numeric':
$sql .= '('.implode(',', $attributes['CONSTRAINT']).')';
break;
case 'enum':
case 'set':
$sql .= '("'.implode('","', $attributes['CONSTRAINT']).'")';
break;
default:
$sql .= '('.$attributes['CONSTRAINT'].')';
}
}
}
if (array_key_exists('UNSIGNED', $attributes) && $attributes['UNSIGNED'] === TRUE)
{
$sql .= ' UNSIGNED';
}
if (array_key_exists('DEFAULT', $attributes))
{
$sql .= ' DEFAULT \''.$attributes['DEFAULT'].'\'';
}
if (array_key_exists('NULL', $attributes) && $attributes['NULL'] === TRUE)
{
$sql .= ' NULL';
}
else
{
$sql .= ' NOT NULL';
}
if (array_key_exists('AUTO_INCREMENT', $attributes) && $attributes['AUTO_INCREMENT'] === TRUE)
{
$sql .= ' AUTO_INCREMENT';
}
}
// don't add a comma on the end of the last field
if (++$current_field_count < count($fields))
{
$sql .= ',';
}
}
return $sql;
}
What you can do is the following in the up method just before the closing tag of it:
$this->db->query("ALTER TABLE `" . $this->db->dbprefix . $this->table_name . "` CHANGE `post_id` `post_id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 'Unique post id'");
Is there any other way to do it without including the column definition in MySQL? No
Note:
Altering a comment will cause a full resconstruction of the table. So you may choose to live without it on very big table.
The Best solution would be to create, extend or copy the mysql or mysqli and reimplementing the _process_fields to handle the comment of the fields. This link can help get you started and this is the advanced.

Drupal Tableselects

I can (finally!!!) set a query to return results for a checkbox(es) set within a collapsible fieldset in Drupal 7- however when I try to put it into a tableselect, I get no results. Would someone be able to check out this code and see if you can tell me why? I also have a screen shot of both results- but since I am new here it won't allow me to post it.
$form = array();
$secnum = 1;
$result = db_query('SELECT s.secser_id, s.ser_name FROM {secser} s WHERE s.sec_num = :secnum', array(':secnum' => $secnum));
$options = array();
foreach ($result as $record) {
$options[$record->secser_id] = $record->ser_name;
}
$form['secser']['1'] = array(
'#title' => t('Basic Sanitation'),
'#type' => 'fieldset',
'#collapsible' => TRUE,
);
$form['secser']['1']['secser'] = array(
'#title' => t('Choices'),
'#type' => 'checkboxes',
'#multiple' => TRUE,
'#options' => $options,
'#description' => t('choose!'),
);
$form['secser']['2'] = array(
'#title' => t('Community Systems'),
'#type' => 'fieldset',
'#collapsible' => TRUE,
);
$secnum = 2;
$result = db_query('SELECT s.secser_id, s.ser_name FROM {secser} s WHERE s.sec_num = :secnum', array(':secnum' => $secnum));
$opt2 = array();
foreach ($result as $record) {
$opt2[$record->secser_id] = $record->ser_name;
}
$header = array(
'ser_name' => t('Choose Service(s)'),
);
$form['secser']['2']['secser'] = array(
'#type' => 'tableselect',
'#title' => t('Community Systems'),
'#header' => $header,
'#options' => array($opt2),
'#multiple' => TRUE,
);
I haven't tried running your code, but it looks like your options are an array which contains another array.
#options' => array($opt2),
because $opt2 is an array, this should be:
#options' => $opt2,
the same way you have the options set up in your checkboxes