I need to generate unique slug based on user input with this code:
public function create_slug($id, $name){
$count = null;
$name = url_title($name);
while(true) {
$this->db->select('id');
$this->db->where('id !=', $id);
$this->db->where('slug', $name);
$query = $this->db->get('users');
if ($query->num_rows() == 0) {
break;
} else {
$name .= '-' . (++$count);
}
}
return $name;
}
It select everything that mach the slug ($name), except its own slug.
The result for first user input - 123 is slug - 123. For second same input the slug is 123-1, but third input with same text is with result 123-1-2, which is not what I want.
I tried another way :
public function create_slug($id, $name){
$count = null;
$name = url_title($name);
$this->db->select('id');
$this->db->where('id !=', $id);
$this->db->where('slug', $name);
$query = $this->db->get('users');
if($query->num_rows()){
$count = '-' . ($query->num_rows() + 1);
}
return $name . $count;
}
Here, is same query, but count rows + 1.
For first 123 the slug is 123;
Second 123, slug 123-2;
Third 123, slug again 123-2, which is not unique.
How can I create slug that is based on some user input and is unique and, if there is slug with value name, next will be name-1, if again, next will be name-2 and etc. ?
You need to create a temp slug_name based on the original name, and test the slug_name. On fail, recreate new slug_name based on original name. On success (breaking out of the loop) return the amended slug_name.
public function create_slug($id, $name)
{
$count = 0;
$name = url_title($name);
$slug_name = $name; // Create temp name
while(true)
{
$this->db->select('id');
$this->db->where('id !=', $id);
$this->db->where('slug', $slug_name); // Test temp name
$query = $this->db->get('users');
if ($query->num_rows() == 0) break;
$slug_name = $name . '-' . (++$count); // Recreate new temp name
}
return $slug_name; // Return temp name
}
Or like this using count_all_results. Removed your id check as well as I presume the slug needs to be unique for the entire table.
public function create_slug($id, $name)
{
$count = 0;
$slug_name = $name = url_title($name);
while(true)
{
$this->db->from('users')->where('slug', $slug_name);
if ($this->db->count_all_results() > 0) break;
$slug_name = $name . '-' . (++$count);
}
return $slug_name;
}
Related
I want to create slug for blog categories. I do it like this;
Str::slug($request->title)
But I have to check if slug exist. If exist, I want to do like this;
// For example title is test. Slug must be test.
// But if slug exist I want to do it test1
if(count(blog_tags::where('slug',$slug)->get()) > 0){
$slug = $slug . '1';
}
// But test1 too can be exist. So I have to test it.
If I test it again and again, system will be slow. What should I do?
Add the following function in your controller class to check ending number in slug
protected function countEndingDigits($string)
{
$tailing_number_digits = 0;
$i = 0;
$from_end = -1;
while ($i < strlen($string)) :
if (is_numeric(substr($string, $from_end - $i, 1))) :
$tailing_number_digits++;
else :
// End our while if we don't find a number anymore
break;
endif;
$i++;
endwhile;
return $tailing_number_digits;
}
Add the following function in your controller class to check slug already exists or not
protected function checkSlug($slug) {
if(blog_tags::where('slug',$slug)->count() > 0){
$numIn = $this->countEndingDigits($slug);
if ($numInUN > 0) {
$base_portion = substr($slug, 0, -$numInUN);
$digits_portion = abs(substr($slug, -$numInUN));
} else {
$base_portion = $slug . "-";
$digits_portion = 0;
}
$slug = $base_portion . intval($digits_portion + 1);
$slug = $this->checkSlug($slug)
}
return $slug
}
Now you will get a unique incremental slug
$slug = $this->checkSlug(Str::slug(string));
Currently I'm using Mysql and CodeIgniters MVC framework to fill in my data. The table logs every status change that has been made and when it was made. This is what the database currently looks like:
I've added new columns in the table called status_from and status_to, where I want these columns to take the substring from action column.
But now how do I display it in my database with my following code:
Controller class:
public function status($status){
$statusar = array('D'=>'Draft','N'=>'Unpublish','Y'=>'Publish','U'=>'Action','L'=>'Unlisted','S'=>'Sold','T'=>'Let');
if($this->input->post('id')){
foreach($this->input->post('id') as $key => $id):
$check = $this->listings_model->loadlisting_check($id);
$log = "Listing website status changed from ". $statusar[$check->status]." to ".$statusar[$status].". The listing ID is #".$id.".";
$this->logs_model->insert_log(array('refno'=>$check->refno,'action'=>trim($log)));
$data=array('status'=>$status);
if($status == 'T' || $status == 'Y' || $status == 'S'){
$pub = 1;
}else{
$pub =0;
}
$this->listings_model->lpupdate(array('property_publish'=>$pub),$id);
endforeach;
}
return true;
}
listings_model:
function loadlisting_check($id)
{
$this->db->select("refno, status, archive");
$id=$this->db->escape_str($id);
$cond=array("$this->table_name.$this->primary_key"=>$id);
$this->db->where($cond);
$this->db->from($this->table_name);
$query = $this->db->get();
return $query->row();
}
logs_model:
public function insert_log($log)
{
$log['agent_id'] = $this->session->userdata('clientsessuserid');
$log['logtime'] = date('Y-m-d H:i:s');
$this->db->insert($this->table_name, $log);
return true;
}
Basically I want to fill my status_from column with $statusar[$check->status] and status_to column with $statusar[$status] when every new entry is made
You can pass the variables you want to add in the array in insert_log method parameter with proper key matched with column name in your table
public function status($status){
$statusar = array('D'=>'Draft','N'=>'Unpublish','Y'=>'Publish','U'=>'Action','L'=>'Unlisted','S'=>'Sold','T'=>'Let');
if($this->input->post('id')){
foreach($this->input->post('id') as $key => $id):
$check = $this->listings_model->loadlisting_check($id);
$log = "Listing website status changed from ". $statusar[$check->status]." to ".$statusar[$status].". The listing ID is #".$id.".";
$this->logs_model->insert_log(array('refno'=>$check->refno,'action'=>trim($log) , 'status_from'=>$statusar[$check->status] ,'status_to'=>$statusar[$status]));
$data=array('status'=>$status);
if($status == 'T' || $status == 'Y' || $status == 'S'){
$pub = 1;
}else{
$pub =0;
}
$this->listings_model->lpupdate(array('property_publish'=>$pub),$id);
endforeach;
}
return true;
}
And you will not need to add anything else to your model
Here i have a list of categories and user can add a new category as well as edit them.
Now at the edit time i'm using server-side validation by codeigniter for reduce redundancies . but the issue is the, whenever i edit an existing category then it can't update it because it compare with their original value, that is wrong. i trying to many time but unable to fix this issue.
Here is my code
public function category_upd()
{
extract($_POST);
$userId = $this->session->userdata('id');
$original_value = $this->db->query("SELECT cat_name FROM category WHERE user_id=".$userId." and cat_name ='".$_POST['cat_name']."'") ;
$original_value = $original_value->result_array();
$original_value = $original_value[0]['cat_name'];
$original_value2 = $this->db->query("SELECT cat_name FROM category WHERE user_id=".$userId." and cat_name ='".$_POST['cat_name']."'") ;
$original_value2 = $original_value2->result_array();
$original_value2 = $original_value2[0]['cat_name'];
if(ucwords($_POST['cat_name']) != $original_value) {
$this->session->set_flashdata('cat_failed','Category must be unique.');
$is_unique = '|is_unique[category.cat_name]';
} else if(ucwords($original_value2 == "")){
echo "go";
exit;
$this->session->set_flashdata('cat_failed','Category must be unique.');
$is_unique = '|is_unique[category.cat_name]';
} else {
$is_unique = '';
}
$this->form_validation->set_rules('cat_name','Category','trim|required'.$is_unique);
if($this->form_validation->run() ) {
A snap with error
I need your kind efforts. Thanks
Set validation Rules like this and you need to pass category id value
$this->form_validation->set_rules('cat_name', 'cat_name', 'required|trim|edit_unique[category.category_name.' . $_POST['category_id'].'.'.$_POST['user_id']. ']', array('edit_unique' => 'Category must be unique.'));
And developed one function edit_unique on Form_validation.php like this
Filepath system/libraries/Form_validation.php
public function edit_unique($str, $field)
{
sscanf($field, '%[^.].%[^.].%[^.].%[^.]', $table, $field,$id, $field2);
return isset($this->CI->db)
? ($this->CI->db->limit(1)->get_where($table, array($field => $str, 'id !=' => $id,'user_id'=>$field2))->num_rows() === 0)
: FALSE;
}
Check category name is alredy in database.
$newcategoryName=$this->input->post('category');
$query = $this->db->get_where('category', array('cat_name' => $newcategoryName,'user_id' => $userId));
$val=$query->result_array();
$original_value = $val[0]['cat_name'];
if($newcategoryName != $original_value) {
$is_unique = '|is_unique[users.EMAIL]';
} else {
$is_unique = '';
}
$this->form_validation->set_rules('cat_name', 'Category', 'required|trim|xss_clean'.$is_unique);
i first checked if there any same problems like mine i ddnt find anything.
all are sorting alphanumeric column mixed with numeric data.
here is my problem.
i have a table that contain column A datas like this.
WRG-01 WRG-39 WRG-22 WRG-45 WRG-43
need to sort that as
WRG-01 WRG-22 WRG-39 WRG-43 WRG-45
this is the code i using so far in codeigniter frame work
$data['products'] = $this->db->order_by('product_id', 'asc')->get('products');
in mysql i can use this query to get done my work
preg_replace("/[^\d]/", "",'product_id'), 'asc')
How to apply it to my above codeigniter code?
here is search funtion
public function search()
{
$data['title'] = 'Search Product';
$product_name = $this->input->get('product_name');
$product_id = $this->input->get('product_id');
$product_category = $this->input->get('product_category');
$secondCategory = $this->input->get('secondCategory');
$thirdCategory = $this->input->get('thirdCategory');
$data['category'] = $this->db->order_by('id', 'asc')->get_where('categories', ['parent' => 0]);
if($product_category != '')
{
$data['secondCategory'] = $this->db->get_where('categories', ['parent' => $product_category]);
}
if($secondCategory != '')
{
$data['thirdCategory'] = $this->db->get_where('categories', ['parent' => $secondCategory]);
}
if($product_name != '')
{
$this->db->like('product_name', $product_name);
}
if($product_id != '')
{
$this->db->where('product_id', $product_id);
}
if($product_category != '')
{
$this->db->where('product_category', $product_category);
}
if($secondCategory != '')
{
$this->db->where('secondCategory', $secondCategory);
}
if($thirdCategory != '')
{
$this->db->where('thirdCategory', $thirdCategory);
}
$data['products'] = $this->db->order_by('product_id' 'asc')->get('products');
theme('all_product', $data);
}
i can't use sql query here because products is result array from product table.
Use MySQL cast
cast(product_id as SIGNED)
or
cast(product_id as UNSIGNED)
Try query like that :-
select * from products cast(product_id as UNSIGNED) ASC|DESC
Try this
$query= $this->db->query("SELECT * FROM products WHERE ??==?? ORDER BY product_id ASC");
$result= $query->result_array();
return $result;
as default data will sort by Ascending Order
This is in model. So if you pass it to controller it will return data as Objective Array.
So in controller you can access
$result = $this->model_name->method_for_above_code();
$name = $result[0]['name'];
$id = $result[0]['id'];
if in View
$result['this_for_view'] = $this->model_name->method_for_above_code();
foreach ($this_for_view as $new_item) {
echo "Name is ".$new_item['name'];
echo "ID is ".$new_item['id'];
}
I want to get unique slug for my articles. I am using codeigniter. I was wondering to have some thing like sample-title-1 and sample-title-2 if there are two articles that have the same title like codeignier does with file upload filename(:num) . I could not figure out a way to do it. I am not an expert on codeigniter. I am learning it.
I prepared a function, when passed a string $str it checks if the slug exists, if it does, it adds the ID of that article to the end of that slug and returns it, if not, it returns the slug.
It is working fine and serving the purpose of unique slug. But what I wanted was to have something like sample-title-1 and sample-title-2 . Is there any way to do so?
$data['slug'] = $this->get_slug($data['title']);
public function get_slug ($str)
{
$slug = url_title($str, 'dash', true);
// Do NOT validate if slug already exists
// UNLESS it's the slug for the current page
$id = $this->uri->segment(4);
$this->db->where('slug', $slug);
! $id || $this->db->where('id !=', $id);
$category = $this->category_m->get();
if (count($category)) {
return $slug.$id;
}
return $slug;
}
easy to use and really helpful to create unique slugs have look on CI slug library
read its documentation to implement it.
what i used to do is to make slug db field UNIQUE.
Then easly do all with the CI helpers Url Helper and Text Helper
$last_id_inserted = //get from db the last post's ID;
$post_title = "My slug would be";
$slug = mb_strtolower(url_title(convert_accented_characters($post_title))).'-'.$last_id_inserted;
echo $slug;
//outputting my-slug-would-be-123
//insert the new post with slug
So ID will be unique and slug too.
I think you need something like that:
//Database loaded
//Text helper loaded
function post_uniq_slug($slug, $separator='-', $increment_number_at_end=FALSE) {
//check if the last char is a number
//that could break this script if we don't handle it
$last_char_is_number = is_numeric($slug[strlen($slug)-1]);
//add a point to this slug if needed to prevent number collision..
$slug = $slug. ($last_char_is_number && $increment_number_at_end? '.':'');
//if slug exists already, increment it
$i=0;
$limit = 20; //for security reason
while( get_instance()->db->where('slug', $slug)->count_all_results('posts') != 0) {
//increment the slug
$slug = increment_string($slug, $separator);
if($i > $limit) {
//break;
return FALSE;
}
$i++;
}
//so now we have unique slug
//remove the dot create because number collision
if($last_char_is_number && $increment_number_at_end) $slug = str_replace('.','', $slug);
return $slug;
}
Examples:
post_uniq_slug('sample'); //"sample" exists
//sample-1
post_uniq_slug('sample-2013'); //"sample-2013" exists
//sample-2013-2
post_uniq_slug('sample-2013', '-', TRUE); //increment "sample-2013"
//sample-2014
*NOT TESTED
public function create_slug($name)
{
$table='tradeshow'; //Write table name
$field='slug'; //Write field name
$slug = $name; //Write title for slug
$slug = url_title($name);
$key=NULL;
$value=NULL;
$i = 0;
$params = array ();
$params[$field] = $slug;
if($key)$params["$key !="] = $value;
while ($this->db->from($table)->where($params)->get()->num_rows())
{
if (!preg_match ('/-{1}[0-9]+$/', $slug ))
$slug .= '-' . ++$i;
else
$slug = preg_replace ('/[0-9]+$/', ++$i, $slug );
$params [$field] = $slug;
}
return $alias=$slug;}