CodeIgniter - Dynamic URL segments - codeigniter

I was wondering if someone could help me out.
Im building a forum into my codeigniter application and im having a little trouble figuring out how i build the segments.
As per the CI userguide the uri is built as follows
www.application.com/CLASS/METHOD/ARGUMENTS
This is fine except i need to structure that part a bit different.
In my forum i have categories and posts, so to view a category the following url is used
www.application.com/forums
This is fine as its the class name, but i want to have the next segment dynamic, for instance if i have a category called 'mycategory' and a post by the name of 'this-is-my-first-post', then the structure SHOULD be
www.application.com/forums/mycategory/this-is-my-first-post
I cant seem to achieve that because as per the documentation the 'mycategory' needs to be a method, even if i was to do something like /forums/category/mycategory/this-is-my-first-post it still gets confusing.
If anyone has ever done something like this before, could they shed a little light on it for me please, im quite stuck on this.
Cheers,

Nothing is confusing in the document but you are a little bit confused. Let me give you some suggestions.
You create a view where you create hyperlinks to be clicked and in the hyperlink you provide this instruction
First Post
In the controller you can easily get this
$category = $this->uri->segment(3);
$post = $this->uri->segment(4);
And now you can proceed.
If you think your requirements are something else you can use a hack i have created a method for this which dynamically assign segments.
Go to system/core/uri.php and add this method
function assing_segment($n,$num)
{
$this->segments[$n] = $num;
return $this->segments[$n];
}
How to use
$this->uri->assign_segment(3,'mycategory');
$this->uri->assign_segment(4,'this-is-my-first-post');
And if you have error 'The uri you submitted has disallowed characters' then go to application/config/config.php and add - to this
$config['permitted_uri_chars'] = 'a-z 0-9~%.:_\-';

You could make a route that forwards to a lookup function.
For example in your routes.php add a line something like;
$route['product/(:any)/(:any)'] = "forums/cat_lookup/$1/$2";
This function would then do a database lookup to find the category.
...
public function cat_lookup($cat, $post) {
$catid = $this->forum_model->get_by_name($cat);
if ($catid == FALSE) {
redirect('/home');
}
$post_id = $this->post_model->get_by_name($post);
/* whatever else you want */
// then call the function you want or load the view
$this->load->view('show_post');
}
...
This method will keep the url looking as you want and handle any problems if the category does not exist.Don't forget you can store the category/posts in your database using underscores and use the uri_title() function to make them pretty,

Set in within config/routes.php
$route['song-album/(:any)/:num'] = 'Home/song_album/$id';
fetch in function with help of uri segment.
$this->uri->segment(1);

Related

Code igniter url segment

currently my website url is
https://www.thefoolsbookie.com/main/inside?id=8
but I want this to be like this
https://www.thefoolsbookie.com/nfl
How can I do this?
Edit the application/config/routes.php file and add a new route for it
$route['nfl'] = 'main/inside';
It should be as simple as that :)
See https://ellislab.com/codeigniter/user-guide/general/routing.html for more examples.
Edit
I've worked with CI for a long time and I've never seen it use GET params in the routes file in that way. I'm not sure it is possible.
You could have it like $route['nfl'] = 'main/inside/8';
then in the main controller your inside method would look like:
public function inside($id)
{
//$id would contain the ID of 8 when you go to
//https://www.thefoolsbookie.com/main/inside/8
//or https://www.thefoolsbookie.com/nfl
}

CodeIgniter hide post id and only slug URL

I'm working on custom blog based on CodeIgniter. Got some problems at the moment I've achieved url:
/blog/view/1/my-very-first-post
I'm not happy with that I'd like to get rid off id and "/view"
That's how my controller looks like:
function index($postId=null)
{
$this->view($postId=null);
}
function view($postId, $str_slug = '')
{
$data['title'] = ucfirst("Blog");
$data['post'] = $this->posts->get_posts($postId);
if($postId !== null)
{
$this->load->view('templates/head', $data);
$this->load->view('templates/header', $data);
$this->load->view('posts/single_view', $data);
$this->load->view('templates/footer',$data);
} else {
$this->load->view('templates/head', $data);
$this->load->view('templates/header', $data);
$this->load->view('posts/index', $data);
$this->load->view('templates/footer',$data);
}
$row = $this->db->get_where('posts', array('id' => $postId))->row();
if ($row and ! $str_slug) {
$str_slug = url_title($row->title, 'dash', TRUE);
redirect("blog/view/{$postId}/{$str_slug}");
}
}
What is the best way to achieve this?
Thanks!!
Adam
I think you're looking for the _remap() method. You can read more about it here: http://ellislab.com/codeigniter/user-guide/general/controllers.html#remapping
Your code would look something like below. You still need to implement the get_posts_by_slug() method if you still need it.
public function _remap($slug) {
$data['title'] = ucfirst("Blog");
$data['post'] = $this->posts->get_posts_by_slug($slug);
if($slug !== null)
{
$this->load->view('templates/head', $data);
$this->load->view('templates/header', $data);
$this->load->view('posts/single_view', $data);
$this->load->view('templates/footer',$data);
} else {
$this->load->view('templates/head', $data);
$this->load->view('templates/header', $data);
$this->load->view('posts/index', $data);
$this->load->view('templates/footer',$data);
}
$row = $this->db->get_where('posts', array('slug' => $slug))->row();
}
Update:
Hey #AdamLesniak - it's generally good design to store a permalink to a blog post or a news article, so that it's not dependent on the title or any other volatile data structure in order to still be accessible.
But for a different approach, personally, I really think this is a nice system:
http://localhost/blog/my-news-article-title-permalink/3
The main issue is that if you don't store the slug/permalink somewhere, then you're going to feel sad when somebody changes the title of an article. Example, my article called "Hello World First Blog Post", which is accessible at:
http://localhost/blog/hello-world-first-blog-post
Changes into "First post I ever made":
http://localhost/blog/first-post-i-ever-made
So what happens to the initial URL? It's no longer accessible - any user that comes on the website via a search engine, or through somebody's link will now no longer see your comment and will instead get a 404 page, which you want to avoid.
A problem with using permalinks on their own is that you need to make sure they're unique, and extra constraints need to be set in place for that.
There are a few tricks that you can do, but they all have their pitfalls. You can for instance use the system I've mentioned above, where you stick the unique identifier at the end of the URL:
http://localhost/blog/hello-world/3
And if the title changes, you don't really care, because you're not using the slug to make your searches, but instead, you're relying on the unique identifier.
http://localhost/blog/first-post-i-ever-made/3
However I've seen opinions that this sort of system is against the idea of an URL (Uniform Resource Locator). I've used it in back when I was starting out, and it proved to be a flexible system; it's definitely nice to experiment with at least.
BBC do a variant of the above, by keeping the category that an article belongs to and the unique identifier for the entry:
http://www.bbc.co.uk/news/business-24511283
Basically, they know that an article will never change its category, although it may change its title, so they just keep the general topic, which is business and the unique identifier 24511283.
In the end, what I suggest you do, as it's by far the most scalable solution is to just generate the following format:
http://localhost/blog/permalink/unique-id
The format above lets you have unique identifiers, which are important for guaranteeing singularity, and permalinks for all the search engine friendly-ness! Now if the title of the article changes, display the updated title to the user on the page, but don't do anything to the permalink, so that your URLs never change.
By also using IDs in the URL, you know for sure that you can use a permalink multiple times, and your system will still scale correctly.
I wrote a tutorial on this which may or may not help: http://www.rappasoft.com/tutorials/14-seo-friendly-links-with-codeigniter.html

Laravel how to route old urls

I am using Laravel 4.
I have an old url that needs to be routable. It doesn't really matter what it's purpose is but it exists within the paypal systems and will be called regularly but cannot be changed (which is ridiculous I know).
I realise that this isn't the format url's are supposed to take in Laravel, but this is the url that will be called and I need to find a way to route it:
http://domain.com/forum/index.php?app=subscriptions&r_f_g=xxx-paypal
(xxx will be different on every request)
I can't figure out how to route this with laravel, i'd like to route it to the method PaypalController#ipbIpn so i've tried something like this:
Route::post('forum/index.php?app=subscriptions&r_f_g={id}-paypal', 'PaypalController#ipbIpn');
But this doesn't work, infact I can't even get this to work:
Route::post('forum/index.php', 'PaypalController#ipbIpn');
But this will:
Route::post('forum/index', 'PaypalController#ipbIpn');
So the question is how can I route the url, as it is at the top of this question, using Laravel?
For completeness I should say that this will always be a post not a get, but that shouldn't really make any difference to the solution.
Use this:
Route::post('forum/{file}', 'PaypalController#ipbIpn');
And then in the controller, use
public function forum($file) {
$request = Route::getRequest();
$q = (array) $request->query; // GET
$parameters = array();
foreach($q as $key => $pararr) {
$parameters = array_merge($parameters, $pararr);
}
}
You can then access the get parameters via e.g.
echo $parameters['app'];
you can use route redirection to mask and ending .php route ex:
Route::get('forum/index', ['uses'=> 'PaypalController#ipbIpn']);
Route::redirect('forum/index.php', 'forum/index');

Magento returning incorrect customer data on frontend pages

isn't this the right method to get Name of logged in customer?
<?php echo Mage::helper('customer')->getCustomer()->getName(); ?>
I have a website with live chat functionality. Yesterday I have been asked to pass email address and the name of the logged into the user into the Javascript Tracking variable code placed in the head section of the website. So that the operators could see who is on the website and whom are they talking to without any need to ask about their information.
So I passed the information from Magento into the Javascript code but now I see this very strange thing happening. For example,
If I am logged in with credentials Name = John Email =
john12#yahoo.com
Then This name and email variable values are changing with the change of pages. For example if I click on any product page the variable values which I am passing changes to some other user's information.
Name becomes Ricky Email becomes ricky23#gmail.com
this variable values are kept on changing back to john and from john to something else with the change of pages. So operator does not have any idea whom are they talking because the values are kept on changing. Also, user ricky or who ever it changes to also exist in the database. so it is picking up random person from the database.
This is what i did to pass the code to javascript. Please let me know if that is not the right code to pass the information. Please check the php code I am using to fetch information from Magento. Roughly, I receive incorrect value once in 5 times. Please provide some assistance. Thanks in advance.
<?php
$customer = Mage::getSingleton('customer/session')->getCustomer();
$email = $customer->getEmail();
$firstname = $customer->getFirstname();
$lastname= $customer->getLastname();
$name = $firstname . ' ' . $lastname;
?>
<script type="text/javascript">
if (typeof(lpMTagConfig) == "undefined"){ lpMTagConfig = {};}
if (typeof(lpMTagConfig.visitorVar) == "undefined"){ lpMTagConfig.visitorVar = [];}
lpMTagConfig.visitorVar[lpMTagConfig.visitorVar.length] = 'Email=<?php echo $email; ?>';
lpMTagConfig.visitorVar[lpMTagConfig.visitorVar.length] = 'Name=<?php echo $name; ?>';
</script>
I'm also attaching a snap shot
I'd be interested to hear how you're adding this code to the page? Is it in it's own block, or are you adding it to footer.phtml, or similar? If your adding to an existing block be sure to check the block caching settings of that template.
To confirm the caching hypothesis I'd ask the following:
Do you get the same name, all the time, on the same page? When you refresh the page, do you get the same name and email in the Javascript?
Does the problem persist with caching disabled?
This doesn't sound like a singleton problem at all. Each execution of the PHP script is isolated from the others, serving one page request. There's no chance of another customer's object moving between invokations of the script.
It is a matter of understanding the singleton pattern. If you call your code twice:
$customer_1 = Mage::helper('customer')->getCustomer()->getName();
$customer_2 = Mage::helper('customer')->getCustomer()->getName();
you get two different instances of the object. But... if one of them has already implemented a singleton pattern in its constructor or has implemented a singleton getInstance then both objects will actually point to the same thing.
Looking at the customer/helper/Data.php code you can see the function
public function getCustomer()
{
if (empty($this->_customer)) {
$this->_customer = Mage::getSingleton('customer/session')->getCustomer();
}
return $this->_customer;
}
That means that in one of the cases singleton is already implemented/called and in other one - not as the property is already set.
The correct way to work with quote/customer/cart in order to get always the correct data is always to use the singleton pattern.
So using this:
$customer = Mage::getSingleton('customer/session')->getCustomer();
always guarantee that you get the correct customer in that session. And as may be you know singleton pattern is based on registry pattern in app/Mage.php:
public static function getSingleton($modelClass='', array $arguments=array())
{
$registryKey = '_singleton/'.$modelClass;
if (!self::registry($registryKey)) {
self::register($registryKey, self::getModel($modelClass, $arguments));
}
return self::registry($registryKey);
}
and looking at app/Mage.php:
public static function register($key, $value, $graceful = false)
{
if (isset(self::$_registry[$key])) {
if ($graceful) {
return;
}
self::throwException('Mage registry key "'.$key.'" already exists');
}
self::$_registry[$key] = $value;
}
...
public static function registry($key)
{
if (isset(self::$_registry[$key])) {
return self::$_registry[$key];
}
return null;
}
you can see that Magento checks is it is already set. If so, Magento will either throw an Exception, which is the default behavior or return null.
Hope this will help you to understand the issue you face.
I have sorted this out. I have moved the code from footer.phtml to head.phtml and it's working fine now.Values are not changing anymore. If anyone know the logic behind please post and I will change my answer. So far this is working.

filter a string to remove disallowed characters to compose an URL in CodeIgniter

I'm trying to make URL-friendly links for the blog on my portfolio.
So I would like to obtain links something like site/journal/post/{title}
Obviously Journal is my controller, but let's say my title would be 'mysite.com goes live!' I would like to have a valid url like site/journal/post/mysitecom-goes-live where all disallowed characters are removed.
How would I transform 'mysite.com goes live!' to 'site/journal/post/mysitecom-goes-live' in CodeIgniter based on the characters in $config['permitted_uri_chars']
use the url helper
$this->load->helper('url');
$blog_slug = url_title('Mysite.com Goes live!');
echo $blog_slug //mysitecom-site-goes-live
// might differ slightly, but it'll do what you want.
to generate url-friendly links.
Store this value in a field in your blog table (url_title/url_slug) whatever.
make a function:
class Journal extends controller
{
//make your index/constructor etc
function view($post)
{
$this->blog_model->get_post($post);
// etc - your model returns the correct post,
// then process that data and pass it to your view
}
}
your blog_model has a method get_post that uses CI's
$this->db->where('url_title', $post);
hope that makes sense.
then when you access the page:
site.com/journal/view/mysite-goes-live
the function will pick up "mysite-goes-live" and pass it to the view() function, which in turn looks up the appropriate blog entry in the database.

Resources