I'm trying to learn how to use code ignitor but I've run into a little problem. As with most people when they first use a framework, I too am making a blog. I'm trying to make my view links look like: http://localhost/blog/view/my-blog-post-title and I've gotten that far. But when I get to the actual view method is when I run into problems. Basically I'm my-blog-post-title refers to the 1st record of posts in my database. But the actual title looks like My Blog, Post Title.
So how do I get the id from my-blog-post-title when the original is My Blog, Post Title so I can pull that post from the database? Or should I just use numbers(I don't want to ;_;).
Well, I think the best solution and the easier approach would be to create a column in your posts table, something called "slug", which contains the url_title() output (the moment you create your article, you save that value in this db column as well as the other infos), and query against that instead of using this more complicated method.
So, you grab the last segment of the url, either via $this->uri->segment(3) or just by passing the whole uri to your controllers' method, and query against that column:
class Blog extends CI_Controller {
public function view($slug)
{
$this->load->model('blog_model');
$data['posts'] = $this->blog_model->search_slug($slug);
$this->load->view('myview',$data);
}
}
Model:
function search_slug($slug)
{
$this->db->select('id,title')
->from('posts')
->where('slug',$slug);
$query = $this->db->get();
return $query->row();
}
View 'myview.php':
echo $posts->id;
echo $posts->title;
You should be able to use something like
$parts = explode("/",$_SERVER['REQUEST_URI']);
$title=$parts[(count($parts)-1)];
to turn your url into an array and then grab the title from the last section. string replace the "-" with " " and then do a %like& search in your db for the title. Not sure that's the best approach but should work.
This code can get you as far as extracting the title:
$url_string = "view/my-blog-post-title";
function getOriginal($url_string) {
$url_parts = explode("/",$url_string);
$url_title = $url_parts[1];
$title_parts = array_map("ucfirst",
explode("-",$url_title));
return implode(" ",$title_parts);
}
echo getOriginal($url_string);
Which will output:
My Blog Post Title
The tricky part is where to insert the comma (,). This is tricky because blog post titles may be have more words like my-blog-post-title-some-other-words or my-blog-title-word-word-word. The comma can go anywhere.
If it is always constant that the comma is to be inserted after My Blog (My Blog is constant) then you just do an str_replace after calling getOriginai(..);
echo str_replace("My Blog","My Blog,","My Blog Post Title");
Related
I have a method which returns all jobs by category.
The problem it's when i have spaces in the category name. How could I access those results?
for ex if i access http://localhost/management_system/Job/get_jobs_by_cat/Architecture it will return all the jobs from the Architecture category.
But when i try to access the category Information Technology I can't do it while I have spaces into the url, so I've tried with _ - and i didn't get any response.
How I can fix this issue?
You would likely want to use urldecode() to decode the url parameters in the controller function processing this logic. In your controller, do something like this:
$jobCat = urldecode($this->uri->segment(4));
Then, you would pass $jobCat to your model.
Here are some other Stack Overflow links that might help your cause.
How to pass parameters with space to controller from URL in
codeigniter?
Php - Codeigniter url spaces
what is the use of $this->uri->segment(3) in codeigniter
pagination
You need to URL encode Information Technology.
$category = 'Information Technology';
$encodedCategory = rawurlencode($category);
$url = 'http://localhost/management_system/Job/get_jobs_by_cat/' . $encodedCategory;
echo $url;
// http://localhost/management_system/Job/get_jobs_by_cat/Information%20Technology
I need to be able to access all the data in one of the columns of my table. My initial approach was to do something like this. The column i am trying to access in my database is called 'Tags'
//get all posts
$post = Post::get();
//get all post tags
$post_tags = $post['tags'];
but this returns null. I know there will be an extremely simple way to do it, i am just not seeing it!
EDIT
The reason i am doing this is i have a tagging system in place when something is posted you can add 3 tags which relate to that post. What i am trying to do in the long run is when a tag is clicked it will filter out all the posts with that set tag.
The way this works is when a tag is clicked the user will be redirect to a url like so
//test-site.com/posts/tags/{tag}
so ill be using that tag to then query the database for the results. I have managed to confuse myself in a task i thought would be farily simple!
If your tags are stored in the same table, the problem may be that you are getting a full result set:
Post::get();
When you should get only one row:
Post::first();
So this one might do the trick in this case:
$post = Post::first();
$post_tags = $post->tags;
If you use Post::get() or Post::all(), you'll have to iterate trough the result set to get your info:
foreach(Post::all() as $post)
{
echo $post->tags;
}
I have small problem.
I've coded a full website in php using CodeIgniter framework. One of my modules is search module, it contains text input with keyword and three select lists with filtering criterias.
That's ok, when I'm searching something - result's listing pagination is done via URL like that:
mysite.com/$keyword/$criteria1/$criteria2/$criteria3/$offset
works like a charm.
But when I'm entering into one of my images (it's image gallery) I want to have an option to go into NEXT and PREVIOUS image from my search results - the ones which I entered this image from.
I'm solving this case now in this way - I have session table called 'search_conditions' and I'm storing values of keyword and my three criterias there, but that's quite not comfortable, because why if someone opens second window and search something else there?
Then all of his searches in another windows or tabs are getting the same criteria - because with every new search, user overwrite the session value.
My next and previous functions:
public function next($count)
{
$search = $this->session->userdata('search_conditions'); //getting session table and overwriting it
$catid = isset($search['catid'])?$search['catid']:'0';
$brandid = isset($search['brandid'])?$search['brandid']:'0';
$prodid = isset($search['prodid'])?$search['prodid']:'0';
$keyword = isset($search['keyword'])?$search['keyword']:'';
$res = $this->search_model->main_search($keyword, $catid, $brandid, $prodid, $count, 1);
}
public function previous($count)
{
$search = $this->session->userdata('search_conditions');
$catid = isset($search['catid'])?$search['catid']:'0';
$brandid = isset($search['brandid'])?$search['brandid']:'0';
$prodid = isset($search['prodid'])?$search['prodid']:'0';
$keyword = isset($search['keyword'])?$search['keyword']:'';
$res = $this->search_model->main_search($keyword, $catid, $brandid, $prodid, $count-2, 1);
}
Can you recommend me some other, more comfortable solution, because this seems not to be good...
: )
Thank you!
Add an index to the $search_conditions variable:
$search_conditions[1]['catid']
$search_conditions[1]['brandid']
...
then refer to it with a controller's or config variable. This way you can allow one session to store multiple search conditions.
But I would recommend you drop storing the search condition in session. Instead, just pass it with the URI. Session data, in the case you describe, work as an intermediary; you don't need it. Use the Pagination Class and pass the search page number, not the direction (next or previous) to the URI.
Do not worry that the URI may look ugly - it only depends on what user searches for, and it's still friendly to share. Your only concern is if the GET string does not extend the limited length.
Pull the segments from the URI in your next() and previous() functions. Use the codeigniter URL helper. That should allow you to pass the different search criterion as variables to the next page, this would also remove your need to use the session.
I am creating a website using the MVC structure. Below is a code I have used to use clean URLS and load the appropriate files. However it only works for the first level.
Say I wanted to visit mywebsite.com/admin it would work, however mywebsite.com/admin/dashboard would not. The problem is in the arrays, how could I get the array to load content after the 2nd level along with the second level.
Would it be best to create an array like this?
Array
- controller
- view
- dashboard
Any help here would be great. Also as a side question. What would be the best way to set up "custom" urls. So if I were to put in mywebsite.com/announcement it would check to see if its got controllers, failing that, check to see if it's got custom content (maybe a file of the same name in "customs" folder, and then if there's nothing execute the 404 page not found stuff) This isn't a priority question though, but loosely associated in how the code works so I thought it best to add.
function hook() {
$params = parse_params();
$url = $_SERVER['REQUEST_URI'];
$url = str_replace('?'.$_SERVER['QUERY_STRING'], '', $url);
$urlArray = array();
$urlArray = explode("/",$url);
var_dump($urlArray);
if (isset($urlArray[2]) & !empty($urlArray[2])) {
$route['controller'] = $urlArray[2];
} else {
$route['controller'] = 'front'; // Default Action
}
if (isset($urlArray[3]) & !empty($urlArray[3])) {
$route['view'] = $urlArray[3];
} else {
$route['view'] = 'index'; // Default Action
}
include(CONTROLLER_PATH.$route['controller'].'.php');
include(VIEW_PATH.$route['controller'].DS.$route['view'].'.php');
var_dump($route['controller']);
var_dump($route['view']);
var_dump($urlArray);
var_dump($params);
// reseting messages
$_SESSION['flash']['notice'] = '';
$_SESSION['flash']['warning'] = '';
}
// Return form array
function parse_params() {
$params = array();
if(!empty($_POST)) {
$params = array_merge($params, $_POST);
}
if(!empty($_GET)) {
$params = array_merge($params, $_GET);
}
return $params;
}
Can you clarify this: "The problem is in the arrays, how could I get the array to load content after the 2nd level along with the second level."
I don't understand how you want this thing to work. I checked your code and it works. Maybe you just need to put $urlArray[1] instead of $urlArray[2] and 2 instead of 3? First element in the array is at index 0.
Usually it's done like this:
Url format:
/controller/action/param1/param2/...
-controller- should be a class. That class has a method/function called -action-.
ex. /shoes/show/121/ --> this will load controller shoes
and execute the method/function show(121)
that will show the shoes that have the id 121 in the
database.
ex. /shoes/list/sport --> this will load controller shoes
and execute function list('sport') that will list all
shoes in the sport category.
As you can see, you only load one controller and from that controller you run only one function and that function will get the rest of the path and use it as parameters.
If you want to have multiple controllers for one URL, then the rest of the controllers will have to be loaded from the main controller. Most MVCs (like CodeIgniter) load only one controller per URL.
Second question:
Best way for pretty urls would be to save them in the db. This means you can have URLs like this:
/I-can-write-anything-here-No-need-to-add-ids-or-controller-names
Then you take this URL and search it in db and get the -controller- and -action- that you need for this URL.
But I have yet to see a popular MVC framework do this. I guess the reason is that the db will get a lot of queries for text matches and that will slow things down.
Popular MVC frameworks use:
/controller/action/param1/param2
This has the benefit that you can directly find the controller/action from the url.
The downside is that you will get urls like:
/shoes/list/sport
//when what you really want is
/shoes/sport
//or just
/sport //if the website only sells shoes
This can be fixed by redirecting /shoes/sport to /shoes/list/sport
If you make your own MVC then you should use OOP because if not, thing will get ugly quick: all actions/functions are in the same namespace.
Personally I would recommend that you use one of the many PHP frameworks that exist as that will take care of the routing for you and let you concentrate on writing your application. CakePHP is one that I've used for a while and it makes my life so much easier.
What I do:
I create a .htaccess file that redirects an url like www.example.com/url/path/or/something to www.example.com/index.php?url=url/path/or/something, so it will be pretty easy to do an explode on your $_GET['url']
Second, it's better because everything a user input, will be redirected to your index.php, so you have FULL control over EVERYTHING.
If you want I can PM you the url to my mvc (bitbucket) so you can have a look on how I do this ;)
(Sorry for the others, but I don't like to put url's to my site in public)
edit:
To be more precise to your particular question; It will solve your problem, because everything goes to index.php and you have full control over the requested url.
I am using following class to show a grid like appearance with pagination on my home page. The class is very good and is working fine.
When the grid shows records, I just want to make the second column values as a hyperlink. I tried adding a href ... in the class where $c is updating, but it is not working. Can anyone help me out.
This class also uses "style.css" file that is also available from the link below. Are any changes needed there?
http://www.webmastergate.com/php/paginate-query-results.html
In the function getRows(), near the very last lines of the function where the $c variable is set. You have to somehow test whether this is the column you want to add the link. Suggest that you set up another associative array which store a key and a callback function
$r = '';
while ($row = mysql_fetch_assoc($result)) {
$c = '';
foreach($row as $key=>$field) {
//manipulate data here
$c .= $this->fmtField($key, $field);
}
$r .= sprintf($this->rowfmt, $cr ? $classodd : $classeven, $c);
$cr = 1 - $cr;
}
Another datagrid I will recommend is http://www.eyesis.ca/projects/datagrid.html - it partly removes the need to add in link as you can add custom actions to each row.
You can't. You can delegate the responsibility to the formatting to the mysql query for a possible workaround.
for example you can format the query like this one:
SELECT firstField,
concat ('', thirdField,'') as link_column,
....
assuming that in the second field you have the URL and in the third one you saved the text of the link.
Another solution (no text) can be
SELECT firstField,
concat ('', secondField,'') as link_column,
....
If you need to show the URL other than make the link.
I've perused the class and think there aren't other solution without modifying it because you can't address a single column in a row.