edit
my solution in routes.php:
$route['news'] = 'news_controller';
$route['gallery'] = 'gallery_controller';
$route['(:any)'] = 'sites/$1';
and in my site conroller:
function index($site_id = '') {
//sanitize $site_id.
$this->site = $this->sites_model->get_site($site_id);
//etc.
}
THX to YAN
question:
so i wrote a little CMS with CodeIgniter. The admin can create sites. the site opens automatically when the segment of the url is like one in the DB. eg mysite.com/sites/about will call the "About" site. this works fine.
now i got a problem with my URL. i want this url
http://www.mysite.com/sites/about
turns to this:
http://www.mysite.com/about
the problem is, that i cannot use the routes.php and set wildcards for each site. (because they are dynamic and i dont know wich site the customer will create - and i dont want to edit the routes.php file for each site he will create - this should be done automatically)
the problem is i got other fix controllers too, like news, gallery or contact:
mysite.com/news, mysite.com/gallery, ...they work fine
so here is my Site Controller:
class Sites extends Public_Controller {
public $site;
public $url_segment;
public function _remap($method)
{
$this->url_segment = $this->uri->segment(2);
$this->load->model('sites_model');
$this->site = $this->sites_model->get_site($this->url_segment);
if($this->site !== FALSE)
{
$this->show_site($this->site);
}
else
{
show_404($this->url_segment);
}
}
public function show_site($data)
{
$this->template->set('site', FALSE);
$this->template->set('site_title', $data['name']);
$this->template->set('content',$data['content']);
$this->template->load('public/template','sites/sites_view', $data);
}}
and this is the Site_model who checks the database...if the url_segment fits the title in the DB:
class Sites_model extends CI_Model {
public function get_site($site_url)
{
if($site_url != ""){
$this->db->where('name', $site_url);
$query = $this->db->get('sites', 1);
if($query->num_rows() > 0){
return $query->row_array();
}
else
{
return FALSE;
}
}else{
return FALSE;
}
} }
i think i need something who checks if the controller exists (the first segment of the url) when not call the Site controller and check if the site is in the DB and when this is false then call 404.
any suggestions how this can be solved?
btw: sry for my english
regards GN
You can handle routes.php in the following way, just keep the (:any) value last:
$route['news'] = 'news_controller';
$route['gallery'] = 'gallery_controller';
$route['(:any)'] = 'sites/$1';
In your sites controller route to the specific site using the data from the URL.
function index($site_id = '') {
//sanitize $site_id.
$this->site = $this->sites_model->get_site($site_id);
//etc.
}
I am having trouble understanding the full intent of the question, but, from what I can tell, don't you simply need to add:
if ($this->uri->segment(1) != 'sites')
... // handle malformed URL
Related
I have an observer action setup, that checks if a product page is loaded. If so, it calls a custom help that deals with all of the GET paremeters. It used to work for over 4 years and have suddenly stopped (the only thing that changed on the 3rd party's side is the naming of those parameters).
Here is the observer action:
public function productView($observer) {
/*#var $block Mage_Core_Block_Abstract*/
$block = $observer->getEvent()->getBlock();
if ($block && $this->getProduct()){
if ($block->getModuleName() == 'Mage_Catalog'){
$productId = $this->getProduct()->getEntityId();
//If params exist - save
if ($this->ParamsHelper()->saveParams($productId)){
//code omitted
}
}
}
}
Here is the helper's action:
public function saveParams($productId) {
if (is_numeric($productId)){
$params = Mage::app()->getRequest()->getParams();
if (!empty($params['image']) && !empty($params['config'])){
//never gets here
return true;
}
}
return false;
}
If I try to var_dump the $params, I get the following array which only includes product_id:
array(1) { ["id"]=> string(3) "664" }
Expected result is to be able to access all the GET parameters passed via url in product view.
Any help or guidance is much appreciated.
EDIT
Product URLs are similar to product names, like f.e.:
domain.com/red-jacket
In a perfect case, I would expect to get parameters passed like following:
domain.com/red-jacket?param1=aaa¶m2=bbb
Not sure whats the exact problem is ... but for domain.com/red-jacket?param1=aaa¶m2=bbb you can get parameters in this way:
$params = Mage::app()->getRequest()->getParams();
$param1 = $params['param1']
or
$param1 = Mage::app()->getRequest()->getParam('param1');
//code for get parameters in view page.
$arrParams = Mage::app()->getRequest()->getParams();
echo "Get Parameter"; echo '<pre>', print_r($arrParams);
I'm struggling with a special little problem related to the redirect out of some Magento observer.
I wrote an extension and put an observer to the "checkout_submit_all_after" event, which works out just fine. My little extension automatically creates an invoice and sets the order status to processing, once the payment method is "Invoice". Unfortunately the redirect after submitting an order in the one page checkout doesn't work anymore. It always redirects to "checkout/cart" instead of "checkout/onepage/success".
Someone any ideas what I'm doing wrong?
Here's my code:
class Shostra_AutoInvoice_Model_Order_Observer
{
public function __construct()
{
}
public function auto_create_invoice($observer)
{
$order = $observer->getEvent()->getOrder();
if (!$order->hasInvoices()) {
$payment = $order->getPayment()->getMethodInstance()->getTitle();
Mage::log("payment method: " . $payment);
if($payment=="Rechnung"){
Mage::log("autocreating invoice");
$invoice = $order->prepareInvoice();
$invoice->register();
$invoice->pay();
$invoice->save();
$order->setState(Mage_Sales_Model_Order::STATE_PROCESSING, true)->save();
Mage::log("invoice created and saved");
}
$this->addComment('Order automatically set to paid.');
} else {
$this->addComment('no invoices found.');
}
$response = $observer->getResponse();
$response->setRedirect(Mage::getUrl('checkout/onepage/success'));
Mage::getSingleton('checkout/session')->setNoCartRedirect(true);
}
}
Thanks a lot!
Why don't you try sales_order_save_after event and try saving it, so no issues with redirection manually as Magento will take its own course,
you can refer to this link for more explanation
http://inchoo.net/magento/magento-orders/automatically-invoice-ship-complete-order-in-magento/
I am a newbee to codeigniter
I have a website with three pages. (Home about Contact)
I want to put an anchor to each of them and
catch last segment using $this->uri->segment() in controller's index function.
Then using a switch I want to direct to exact pages.
This is one of my anchor:
<h3 id="anchor_storefront"><?php echo anchor('jstorecontroll/home', 'Home'); ?></h3>
And this is my code in index at controller:
switch( $this->uri->segment(2) )
{
case "":
case "home":
$this->load->view('public/home');
break;
}
Can an expert guide me?
Thanks
How about just having a function for each page? This follows CodeIgniter's usual URI pattern example.com/class/function/id/ - something like this:
class Jstorecontroller extends CI_Controller
{
function index()
{
//Do what you want... load the home page?
}
//Load the 'home' page
function home()
{
$this->load->view('public/home');
}
//Load the 'about' page
function about()
{
$this->load->view('public/about');
}
//Load the 'contact' page
function contact()
{
$this->load->view('public/contact');
}
}
Routing can be used to map URLs: To map jstorecontroll as the first segment and anything as the second segment to the index function in your jstorecontroll controller, you could use this route (in application/config/routes.php):
$route['jstorecontroll/(:any)'] = "jstorecontroll/index/$1";
You may want to use regex to restrict what is mapped though, for example:
$route['jstorecontroll/([a-z]+)'] = "jstorecontroll/index/$1";
You could then have a function in your controller that would filter through and load the corresponding page. However, be wary of the user input - don't trust them! Make sure you sanitise the input.
class Jstorecontroll extends CI_Controller
{
function index($page = FALSE) //Default value if a page isn't specified in the URL.
{
if($page === FALSE)
{
//Do what you want if a page isn't specified. (Load the home page?)
}
else
{
switch($page)
{
case "home":
$this->load->view('public/home');
break;
case "about":
$this->load->view('public/about');
break;
case "contact":
$this->load->view('public/contact');
break;
}
}
}
}
The use of the above route may produce undesired results if you have other function in this controller that you want to be called from a URI, they won't be called but instead mapped as a parameter to the index function. Unless you look at changing (or adding) the routes, or you could look into remapping functions. Personally, I'd just use a function for each page!
I have a url like
"www.site.com/index.php/details/productname"
and I get 404 error on that link in codeigniter but the URL www.site.com/index.php/details/ is working fine. I want handle url parameter in seo manner.
You have to add /index/ segment in part of your url:
http://www.site.com/index.php/details/index/productname/
If you want to open url such like that http://www.site.com/index.php/details/productname/:
1) you need to define _remap() method:
public function _remap($method)
{
if ($method == 'index')
{
$this->viewDetails($this->uri->segment(2));
}
else
{
$this->default_method();
}
}
OR
2) use application/config/routes.php file
$route['details/(:any)'] = "products/viewDetails/$1";
From User-Guide:
routers.php
_remap method
I would like to create a custom CMS within Codeigniter, and I need a mechanism to route general pages to a default controller - for instance:
mydomain.com/about
mydomain.com/services/maintenance
These would be routed through my pagehandler controller. The default routing behaviour in Codeigniter is of course to route to a matching controller and method, so with the above examples it would require an About controller and a Services controller. This is obviously not a practical or even sensible approach.
I've seen the following solution to place in routes.php:
$route['^(?!admin|products).*'] = "pagehandler/$0";
But this poses it's own problems I believe. For example, it simply looks for "products" in the request uri and if found routes to the Products controller - but what if we have services/products as a CMS page? Does this not then get routed to the products controller?
Is there a perfect approach to this? I don't wish to have a routing where all CMS content is prefixed with the controller name, but I also need to be able to generically override the routing for other controllers.
If you use CodeIgniter 2.0 (which has been stable enough to use for months) then you can use:
$route['404_override'] = 'pages';
This will send anything that isn't a controller, method or valid route to your pages controller. Then you can use whatever PHP you like to either show the page or show a much nicer 404 page.
Read me guide explaining how you upgrade to CodeIgniter 2.0. Also, you might be interested in using an existing CMS such as PyroCMS which is now nearing the final v1.0 and has a massive following.
You are in luck. I am developing a CMS myself and it took me ages to find a viable solution to this. Let me explain myself to make sure that we are on the same page here, but I am fairly certain that we area.
Your URLS can be formatted the following ways:
http://www.mydomain.com/about - a top level page with no category
http://www.mydomain.com/services/maintenance - a page with a parent category
http://www.mydomain.com/services/maintenace/server-maintenance - a page with a category and sub category.
In my pages controller I am using the _remap function that basically captures all requests to your controllers and lets you do what you want with them.
Here is my code, commented for your convenience:
<?php
class Pages extends Controller {
// Captures all calls to this controller
public function _remap()
{
// Get out URL segments
$segments = $this->uri->uri_string();
$segments = explode("/", $segments);
// Remove blank segments from array
foreach($segments as $key => $value) {
if($value == "" || $value == "NULL") {
unset($segments[$key]);
}
}
// Store our newly filtered array segments
$segments = array_values($segments);
// Works out what segments we have
switch (count($segments))
{
// We have a category/subcategory/page-name
case 3:
list($cat, $subcat, $page_name) = $segments;
break;
// We have a category/page-name
case 2:
list($cat, $page_name) = $segments;
$subcat = NULL;
break;
// We just have a page name, no categories. So /page-name
default:
list($page_name) = $segments;
$cat = $subcat = NULL;
break;
}
if ($cat == '' && $subcat == '') {
$page = $this->mpages->fetch_page('', '', $page_name);
} else if ($cat != '' && $subcat == '') {
$page = $this->mpages->fetch_page($cat, '', $page_name);
} else if ($category != "" && $sub_category != "") {
$page = $this->mpages->fetch_page($cat, $subcat, $page_name);
}
// $page contains your page data, do with it what you wish.
}
?>
You of course would need to modify your page fetching model function accept 3 parameters and then pass in info depending on what page type you are viewing.
In your application/config/routes.php file simply put what specific URL's you would like to route and at the very bottom put this:
/* Admin routes, login routes etc here first */
$route['(:any)'] = "pages"; // Redirect all requests except for ones defined above to the pages controller.
Let me know if you need any more clarification or downloadable example code.