Adding comments to columns in codeigniter migrations - mysql

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.

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,
]);

Drupal 7 function db_insert() causes internal server error (500)

I am building an onsite payment method and among other things I need to save data to a custom db table, after recieving a callback from an external API service.
This is the function:
// callback from external service acting as client
function _api_callback() {
global $user;
$data = json_decode(file_get_contents("php://input"), $assoc = true);
$date = $date['year'] . '-' . $date['month'] . '-' . $date['day'];
$timestamp = strtotime($date);
db_insert('postback')
->fields(array(
'user_id' => $user->uid,
'data' => $data,
'created_date' => $timestamp,
))
->execute(); // save data from external service
}
In the site's access log I can see that my site responds with a 500 code when the external callback arrives.
However if I comment out everything in that function the external callback recieves a 200 response code.
So there is some thing going wrong, when this callback is recieved. It's hard to debug since the callback from the external API service starts a whole new session.
The custom table "postback" was successfully created in the .install file of my custom module and I have checked in phpMyAdmin that the table is present and well. This is the schema() function in the .install file:
function module_payments_schema() {
$schema['postback'] = array(
'description' => 'Data saved from API postback URL.',
'fields' => array(
'id' => array(
'description' => 'Auto incremental id.',
'type' => 'serial',
'unsigned' => TRUE,
'not null' => TRUE),
'user_id' => array(
'description' => 'User id for the order.',
'type' => 'int',
'unsigned' => TRUE,
'not null' => FALSE),
'order_id' => array(
'description' => 'Current order number.',
'type' => 'int',
'unsigned' => TRUE,
'not null' => TRUE,
'default' => 0),
'data' => array(
'description' => 'Postback data from external API.',
'type' => 'varchar',
'length' => 1020,
'not null' => TRUE,
'default' => ''),
'created_date' => array(
'description' => 'Created date and time (yyyy-mm-dd H:i:s).',
'type' => 'varchar',
'mysql_type' => 'DATETIME',
'not null' => TRUE,
),
),
'primary key' => array('id'),
);
return $schema;
}
Anyone who can see what's wrong?
It turns out I needed to format the date value like this...
date('Y-m-d H:i:s');
... in order to work with the mysql DATETIME type.
So the working function now looks like this:
function _api_callback() {
global $user;
$data = json_decode(file_get_contents("php://input"), $assoc = true);
db_insert('postback')
->fields(array(
'user_id' => $user->uid,
'data' => $data,
'created_date' => date('Y-m-d H:i:s');
))
->execute(); // save data from external service
}

Wordpress filter post between dates

So I have created a category in wordpress where I post some events. I have created two custom field where I insert two dates ( duration of the event ). Now my client wants to have 3 sort options ( current, upcoming, past ) that should be present in a dropdown menu.
For that i have managed to create this:
if($_ISSET('sort') && $_GET['sort'] == 'upcoming') {
$args = array(
'post_type' => 'post',
'meta_query' => array(
array(
'key' => 'm77_datefrom',
'value' => date('Y-m-d'),
'compare' => '>'
),
),
);
}
else if($_ISSET('sort') && $_GET['sort'] == 'past'){
$args = array(
'post_type' => 'post',
'meta_query' => array(
array(
'key' => 'm77_datefrom',
'value' => date('Y-m-d'),
'compare' => '<'
),
),
);
}
The problem is that I cannot insert the "sort" parameter.
Url structure : domain.com/category/events
Any ideas how can i solve this problem ? Or is there a better way to do this ?

Drupal 7 form insert if already exists show message like already existed filed

function countries_form($form, &$form_state,$id=0) {
if($id!=0){
$result = db_query('SELECT * FROM {countries} WHERE id = '.$id.'')->fetch();
// print_r($result);exit;
$form['country_name'] = array(
'#type' => 'textfield', //you can find a list of available types in the form api
'#title' => 'Country name',
'#size' => 30,
'#maxlength' => 30,
'#default_value' => $result->country_name,
'#required' => TRUE, //make this field required
);
$form['description'] = array(
'#type' => 'textarea', //you can find a list of available types in the form api
'#title' => 'Description',
'#default_value' => $result->description,
'#required' => TRUE, //make this field required
);
$form['status'] = array(
'#type' => 'radios',
'#title' => t('Status'),
'#default_value' => $result->status,
'#options' => array(
'1' => t('Active'),
'0' => t('Inactive'),
),
);
}else{
$form['country_name'] = array(
'#type' => 'textfield', //you can find a list of available types in the form api
'#title' => 'Country name',
'#size' => 30,
'#maxlength' => 30,
'#required' => TRUE, //make this field required
);
$form['description'] = array(
'#type' => 'textarea', //you can find a list of available types in the form api
'#title' => 'Description',
'#required' => TRUE, //make this field required
);
}
$form['submit_button'] = array(
'#type' => 'submit',
'#value' => t('Click Here!'),
);
return $form;
}
function countries_form_submit($form, &$form_state) {
//$result = db_query('SELECT country_name FROM {countries}')->fetch();
//print_r($result);
if(arg(2)!=0){
$query = db_update('countries')->fields(array('country_name'=>$form_state['values']['country_name'],'description'=>$form_state['values']['description'],'status'=>$form_state['values']['status']))->condition('id',arg(2));
$query->execute();
// print_r($query);
drupal_set_message(t('Country %name has been updated.', array('%name' => $form_state['values']['country_name'])));
//print_r($description);
}else{
//$query = db_update('countries')->fields(array('country_name'=>$form_state['values']['country_name'],'description'=>$form_state['values']['description'],'status'=>$form_state['values']['status']))->condition('country_name','%s');
// print_r($query);
$query = db_insert('countries')->fields(array('country_name'=>$form_state['values']['country_name'],'description'=>$form_state['values']['description']));
//print_r($query);
$query->execute();
drupal_set_message(t('Country %name has been saved.', array('%name' => $form_state['values']['country_name'])));
}
//exit;
$form_state['redirect'] = 'mypages/table';
}
bu using druapl 7 form I am inserting and displaying date and editing and deleting as well all working fine..
now i want ..when inserting form we need to show message if already filed exists country name already taken like that..
there is not update query required only query for while inserting value check weather it is existed or not...
in that the below code is used or edit by passing arguments..
if(arg(2)!=0){
$query = db_update('countries')->fields(array('country_name'=>$form_state['values']['country_name'],'description'=>$form_state['values']['description'],'status'=>$form_state['values']['status']))->condition('id',arg(2));
$query->execute();
// print_r($query);
drupal_set_message(t('Country %name has been updated.', array('%name' => $form_state['values']['country_name'])));
//print_r($description);
}else{
in the else code inserting here we need to check weather existed or not

Using order by FIELD in CakePHP

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',
),
);