ORGINAL QUERY - Updated Query Below
I am in the process of building a custom application in PHP. I know there have been many questions asked about Routing etc. on here and I have spent many of hours reading them all. This is how I got my routing elements to work in the first place. However 1 thing I cant get to fit into my project is peoples suggestions on how to route URLs based on a database entry.
The application itself is working perfectly fine and I already have some URL Routing in place which works exactly how I want it. The issue I have is when I add new products into my database I have a trigger that generates a SEO Friendly URL and stores it in a field in the database.
All the product URLs are structured in the same way.
/North/productdetails/Productname
/South/productdetails/Productname
/NorthEast/productdetails/Productname
etc.
What I am looking to do is not have to manually write a new URL Route into the routes.php file every time a product is added.
this is my .htaccess
RewriteEngine on
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
rewriteRule ^(.+)$ index.php?uri=$1 [QSA,L]
and my index.php file contains:
<?php
header("Cache-Control: no-cache");
include 'System/Config/route.php';
include 'System/Config/settings.php';
connect();
$route = new Route();
include 'System/Config/routeURL.php';
$route->add('/', 'Home');
$route->add('/results', 'Results');
$route->add('/special', 'Special');
$route->gogo();
?>
I need something like this to go in and catch every URL passed to it. It then needs to check the URL and send the relevant information to a page.
$route->add('/results/NorthEast/productdetails/<whateveryisstoredindatabse>', 'productURLS');
The class file that I use at the min to check it is this:
class productURLS
{
function Item($itemID)
{
$host = $_SERVER['SERVER_NAME'] . $_SERVER['REQUEST_URI'];
$itemID = '0';
if($host == host +<URLStored in database>) {
$itemID = <what ever id is in database>;
} else {
$itemID = '0';
$_POST['ShowProductDetails'] = $itemID;
}
public function __construct()
{
productURLS::Item($ItemID);
include 'pages/productdetails.php';
}
}
The class I wrote above is what I use to deter the current URLS onsite, I have modified it to identify where I need help on.
This is the route controller:
class Route
{
private $_uri = array();
private $_method = array();
/**
* Builds a collection of internal URL's to look for
* #param type $uri
*/
public function add($uri, $method = null)
{
$this->_uri[] = '/' . trim($uri, '/');
if ($method != null) {
$this->_method[] = $method;
}
}
/**
* Triggers from start page
*/
public function gogo()
{
$uriGetParam = isset($_GET['uri']) ? '/' . $_GET['uri'] : '/';
foreach ($this->_uri as $key => $value)
{
if (preg_match("#^$value$#", $uriGetParam))
{
$usemethod = $this->_method[$key];
new $usemethod();
}
}
}
}
Does anyone have any suggestions in what I can do with what I have? or will it require a complete rewrite of the routing?
Regards
UPDATED
I have left the original query in as well as this one. For anyone landing on this page I have now been able to obtain data from the database and use it to generate a route in my routing controller dynamically. This is how I did it.
my index.php file now looks like this:
<?php
header("Cache-Control: no-cache");
include 'System/Config/route.php';
include 'System/Config/settings.php';
connect();
$route = new Route();
include 'System/Config/routeURL.php';
$q="SELECT `itemID`,`SEOFriendlyURL` FROM `Products`";
$r=mysql_query($q);
$numrows = mysql_num_rows($r);
if($numrows==0)
{
// Does nothing as the database is empty - Not really needed but good just in case
}
// Dynamic Routing Elements
while($row = mysql_fetch_array($r))
{
$route->add("/results" . $row['SEOFriendlyURL'] ."", 'productURLS');
}
//Static Routing Elements
$route->add('/', 'Home');
$route->add('/results', 'Results');
$route->add('/special', 'Special');
$route->gogo();
?>
This has worked perfectly, When ever one of these URLS is called it diverts to the right page. The only thing I'm having issues with now is passing the relevant ID's via $_post
This is what I ended up with but its not working.
class productURLS
{
function clubs($ItemID)
{
$q="SELECT `itemID`,`SEOFriendlyURL` FROM `products`";
$r=mysql_query($q);
$numrows = mysql_num_rows($r);
if($numrows==0)
{
$ItemID = '0';
}
while($row = mysql_fetch_array($r))
{
$host = $_SERVER['REQUEST_URI'];
$ClubID = '0';
if($host == "/newtest/results" . $row['SEOFriendlyURL'] ."") {
$ClubID = "'" . $row['itemID'] ."'";
} else {
$itemID = '0';
}
}
$_POST['ShowClubDetails'] = $itemID;
}
public function __construct()
{
productURLS::clubs($itemID);
include 'pages/productdetails.php';
}
}
However this doesn't work. Because the query etc. is in the index page is it really needed again here? and is it better to get the query to store the ID in a variable and use that in the function instead?
Regards
I have managed to get this fully working. Here is what I did. May be of some use to someone else.
Index.php
include 'System/Config/routeURL.php';
$q="SELECT `ItemID`,`SEOFriendlyURL` FROM `Products`";
$r=mysql_query($q);
$numrows = mysql_num_rows($r);
if($numrows==0)
{
echo "There's nothing here!";
}
// Add's all SEOFriendly URL's in table into route file (Dynamic)
while($row = mysql_fetch_array($r))
{
$route->add("/results" . $row['SEOFriendlyURL'] ."", 'ProductURLS');
}
routeURL.php
class ProductURLS
{
public function __construct()
{
$host = $_SERVER['REQUEST_URI'];
$host = ltrim ($host, '/results');
$host = "/$host";
$q="SELECT `ItemID`,`SEOFriendlyURL` FROM `Products` WHERE `SEOFriendlyURL` = '$host'";
$r=mysql_query($q);
if($r) {
$row = mysql_fetch_assoc($r);
$ItemID = $row['ItemID'];
} else {
$ItemID = '0';
}
$_POST['ShowClubDetails'] = $ItemID;
//echo "Whole query: $ItemID"; // This is to make sure the ProductID is being passed.
include 'pages/ProductDetails.php';
}
}
Related
I want to set all the advanced search parameter using session how to set all the parameter at time.
I am using following function but it only set one parameter at time how to set all the parameter at time
public function searchterm_handler($searchterm)
{
if($searchterm)
{
$this->session->set_userdata('searchterm', $searchterm);
return $searchterm;
}
elseif($this->session->userdata('searchterm'))
{
$searchterm = $this->session->userdata('searchterm');
return $searchterm;
}
else
{
$searchterm ="";
return $searchterm;
} }
Method one (recommended)
So for pagination in CodeIgniter, you have 3 main variables you must set and a configuration method to call. You also have a library you must load.
The library is $this->load->library('pagination');
The 3 variables and configuration look like this:
//This next line is used mainly so the page number links on your pagination work.
$config['base_url'] = 'http://example.com/index.php/test/page/';
$config['total_rows'] = $NumberOfRecords;
$config['per_page'] = 20;
$this->pagination->initialize($config);
If you are using MVC then this is quite simple. You would use the above code in your controller, grab the data you want to display starting at the nth row, where n is the page number * $config['per_page'], and ending at ((page number * $config['per_page']) + $config['per_page'])-1.
After getting the necessary data you would return that and the link code to your view. The link code is $this->pagination->create_links();
So your return might look something like this:
$data["results"] = $this->MyModel->MySqlMethod($config["per_page"], $CurrentPage);
$data["links"] = $this->pagination->create_links();
Then in your view you would loop through the $data["results"] and after the loop you would display the $data["links"]
This would give you your data displayed then the pagination at the bottom would look something like
So your controller all together should look like:
$config['base_url'] = 'http://example.com/index.php/controllerName/ViewName/';
$config['total_rows'] = $NumberOfRecords;
$config['per_page'] = 20;
$this->pagination->initialize($config);
$data["results"] = $this->MyModel->MySqlMethod($config["per_page"], $CurrentPage);
$data["links"] = $this->pagination->create_links();
return $this->load->view("ViewName", $data);
Method Two (NOT recommended)
Now you mentioned something about storing that data in Session Variables. I mean if you want you can do this. If you are going to use that method, then that tell you are not using MVC. CodeIgniter is meant for MVC. If you are not using MVC then you probably do not need CodeIgniter. If you are comfortable using CodeIgniter and do not want to try and implement the MVC, by all means go ahead.
To do the CodeIgniter Pagination in this method, you would change your public searchterm_handler($searchterm) function. The thing with session variables is that they are stored on the users browser so that way you, the programmer, can access them anywhere on your site without having to return and pass them from class to class or method to method. If you set a session variable then you return it, that is redundent and unnecessary.
You don't really need this method, it is unnecessary, but you could do something like this:
public function searchterm_handler($searchterm) {
$result = mysqli_query("SELECT count(*) FROM User_info");
$row = mysqli_fetch_row($result);
$TotalDataCount = $row[0];
$this->session->set_userdata("TotalDataCount", $TotalDataCount);
$this->session->set_userdata("RecordsPerPage", 20);
$this->session->set_userdata("BaseURL", www.example.com/link/to/your/page.php);
$this->pagination->initialize($config);
if($searchterm) {
$this->session->set_userdata('searchterm', $searchterm);
//Unnecessary
//return $searchterm;
} else {
$this->session->set_userdata('searchterm', "");
//return $searchterm;
}
}
Then in the code that called searchterm_handler($searchterm), you would do this:
searchterm_handler($input);
$searchterm = $this->session->userdata('searchterm');
$dataToReturn = array();
if($searchterm!="") {
$result = mysqli_query("SELECT * FROM table WHERE field LIKE '%$this->session->userdata('searchterm')%'");
if($result->num_rows > 0) {
// output data of each row
while($row = $result->fetch_assoc()) {
echo "id: " . $row["id"]. " - Name: " . $row["firstname"]. " " . $row["lastname"]. "<br>";
}
} else {
echo "0 results";
}
echo $this->pagination->create_links();
LET ME WORN YOU
This second method, is gross and ugly and yucky and very badly written. There is no real good way to write what you want to write. The purpose of using CodeIgniter is for MVC and built in CodeIgniter functionality, which you lose almost all of it when you get rid of MVC.
I know there is a chance I misunderstood what you are trying to do, but this was my best guess. My best advice for you is to use MVC in CodeIgniter.
Here are some sources that may help you if you use the first method:
https://www.sitepoint.com/pagination-with-codeigniter/
https://www.codeigniter.com/userguide3/libraries/pagination.html
I hope this helps, I spent a lot of time writing it...
Update - Method 3
I tried looking at your question again and maybe this will help
public function searchterm_handler($searchterm)
{
if($searchterm && $this->session->userdata('email'))
{ //user logged in
$this->session->set_userdata('searchterm', $searchterm);
$array = array(
"searchterm" => $searchterm,
"email" => $this->session->userdata('email'),
"username" => $this->session->userdata('username')
);
return $array;
}
else if($searchterm && !$this->session->userdata('searchterm'))
{ //user not logged in
$this->session->set_userdata('searchterm', $searchterm);
return $searchterm;
}
elseif($this->session->userdata('searchterm') && $this->session->userdata('searchterm'))
{ //user logged in
$searchterm = $this->session->userdata('searchterm');
$array = array(
"searchterm" => $searchterm,
"email" => $this->session->userdata('email'),
"username" => $this->session->userdata('username')
);
return $array;
}
elseif($this->session->userdata('searchterm') && !$this->session->userdata('searchterm'))
{ //user not logged in
$searchterm = $this->session->userdata('searchterm');
return $searchterm;
}
else
{
$searchterm ="";
return $searchterm;
} }
sorry if this is may, I did it on my phone
I have integrated two applications,one developed using Joomla and other using php mvc.When submit a page in the second aplication it shows
"File 'JDocumenterror' containing class 'JDocumenterror' not
found"
and does not redirect to the intended page.What can be done to remove this error?
Model:
function addPolicy($post)
{
array_pop($post);
//$this->printr($post);die();
$policyBreakDown = $post['rtcPercentage']."_".$post['CecPercentage']."_".$post['partnerRTCPercentage']."_".$post['translationPercentage']."_".$post['otherRTCPercentage'];
if($post['policy_for']<>'DL'){
$getOtherPolicy = $this->getPolicyType($post['policy_for']);
//print_r($getOtherPolicy);
foreach($getOtherPolicy as $data){
$othPolicyID[]=$data->policy_id;
}
if(count($othPolicyID)>0){
//foreach($othPolicyID as $k=>$v){
$ids = implode(",", $othPolicyID);
$data = array("status=0");
$this->updateSQL('tbl_policy', $data,
' policy_id IN ('.$ids.')');
//}
}
}
$id = $this->insert('tbl_policy',array('title'=>$post['title'] , 'description'=>$post['description'] , 'status'=>'1','break_down'=>$policyBreakDown,'policy_for'=>$post['policy_for']));
return $id;
}
Controller:
if(isset($_POST['AddPolicy']))
{
$id = $this->Model->addPolicy($_POST);
$this->redirect('?policy&pg=policy_manage');
}
I have a community site, where people can put up pages, and the url generates from their name. e.g. My Business, becomes my-business. I want to create a way, that if there is another My Business, it will check and make the url my-business-2, my-business-3, etc.
function check_url($url) {
$qry = mysqli_query($this->con, "SELECT * FROM businesses WHERE url LIKE '$url%'");
if(mysqli_num_rows($qry)>0) {
$slugs = array();
while($row = mysqli_fetch_array($qry)) $slugs[] = $row['url'];
if(in_array($url, $slugs)) {
$max = 1;
while(in_array(($url . '-' . ++$max ), $slugs)) $url .= '-' . $max;
}
}
return $url;
}
This is my function, but this still wont work, as if there is a business called My Bus, it will make it my-bus-2, when it would have been unique at my-bus. I have experimented with other functions too, but this one is the closest I got. Can anyone tell me one that works perfectly?
So form my understanding, you are trying to avoid inserting/generating duplicate URL. Output will be something like this -
www.example.com/my-business
www.example.com/my-business-1
www.example.com/my-business-2
www.example.com/my-business-3
...
Try using this function -
function check_url($base_url, $new_url='', $num=0) {
if($new_url == '') {
$new_url = $base_url;
}
$qry = mysqli_query($this->con, "SELECT * FROM businesses WHERE url = '$new_url'");
if(mysqli_num_rows($qry) > 0) {
while($row = mysqli_fetch_array($qry)) {
$num++;
check_url($base_url, $base_url . '-' . $num, $num);
}
}
return $url;
}
Basically, this function will check the database until it finds a valid URL. Each time it will increment the number and recursively call the same function to generate new/valid URL.
Simple and basic!
#SpritsDracula has working code, but his function will query your database each time it executes. That being said, the recursion is a nice concept. Here is a piece of code that will save your the multiple database calls.
function check_url($url) {
$qry = mysqli_query($this->con, "SELECT * FROM businesses WHERE url LIKE '$url%'");
if(mysqli_num_rows($qry)>0) {
$baseUrl = $url;
$slugs = [];
while($row = mysqli_fetch_array($qry)) $slugs[] = $row['url'];
$max = 1;
while(in_array($url, $slugs)) {
$url = $baseUrl . "-" . $max++;
}
}
return $url;
}
Request yo to help in pagination links .
In my database i have 3 records i want to display single record per page. When I select the next numeric of pagination link, data is not being fetched.Thing is that when I click on number 2 of pagination link, echo var_dump() shows Result is empty and I am not getting any values for echo $data->email.But for the first time when i search i am able to display single record, problem is only with next link of pagination So what might be the error? I'm not able to get an answer,and I'm not sure what happens, so I am posting my code below please go through it and and help me.
Request you to help me.
**HERE STARTS MY CONTROLLER**
public function users($limit=1,$offset = 0)
{
$this->load->helper('url');
$data = array();
$look = $this->input->post('look');
$age = $this->input->post('age');
$age_from = $this->input->post('age_from');
$age_to = $this->input->post('age_to');
$se_ct = $this->input->post('sect');
$subsect = $this->input->post('subsect');
$coun_try = $this->input->post('country');
$sta_te = $this->input->post('state');
$ci_ty = $this->input->post('city');
$qualification = $this->input->post('qualification');
$results = $this->searchresultss->login($look, $age, $age_to, $age_from, $se_ct, $subsect, $coun_try, $sta_te, $ci_ty, $qualification);
$this->load->helper('url');
$config = array();
$config['base_url'] = base_url().'searchresult/users';
$config['total_rows'] = count($results);
$config['per_page'] = $limit;
$this->load->library('pagination', $config);
$data['pagination_links'] = $this->pagination->create_links();
$data['results'] = array_slice($results, $offset, $limit);
$this->load->view('searchresult', $data);
$this->load->view('includes/khelp');
$this->load->view('includes/kfooter');
**HERE STARTS MY MODEL PAGE**
Class Searchresultss extends CI_Model
{
public function login($look, $age, $age_to, $age_from, $se_ct, $subsect, $coun_try, $sta_te, $ci_ty, $qualification)
{
return $this->db->query("SELECT *
FROM users
WHERE gender = '$look'
And status='1'")->result();
}
}
**HERE START MY VIEW PAGE**
echo var_dump($_POST);
if (empty($results)) {
echo 'Results set is empty';
} else
{
foreach ($results as $data) {
echo $data->email.'<br />';
}
}
echo $pagination_links;
The problem lies in the fact that the pagination links do not include the POST variables (as well as the fact that hyper links are requested via GET).
I recommend you do a var_dump() on $_GET and $_POST and the problem will become more obvious.
A possible solution would be to include the post variables as url parameters. So for example
$config['base_url'] = base_url().'searchresult/users/look_param/age_param/etcetc';
However you would need to add functionality to handle the above.
Here is my current component setup. I have a very dynamic page generation component that syncs with data from a external API to create pages for products without extra data entry.
Right now it works at a simple button click to populate all and update any changes, or just update individual fields. What this leads to is the generation of static "pages" from the api in joomla, and the ability to update it from the api.
The problem comes into the fact that this is used as the "home" menu item so the component itself takes the root directory. What I need is each "page" to take a sub menu of home automatically, though just setting the main menu item as home does not seem to work, it leads to the JRoute class getting confused and using component/ , everything I have read so far takes the assumption it is not the default menu item so I am losing home making it fully automatic.
So my question is, is there a function class to create menu items from components in joomla? adding another row to the joomla menu table for each page while i update them "should" solve the problem, I know I can try to figure out how joomla adds them to the database on my own, but I would prefer to use a joomla class/function if at all possible, any ideas?
here is my current router.php, works fine for directly linking to the page but not when using JRoute. There is some uneeded parts to this as I have been doing some extensive testing though.
<?php
defined('_JEXEC') or die;
function GoFormsBuildRoute($query){
$segments = array();
$app = JFactory::getApplication();
$menu = $app->getMenu();
$params = JComponentHelper::getParams('com_goforms');
$db = JFactory::getDBO();
if (empty($query['Itemid'])) {
$menuItem = $menu->getActive();
$menuItemGiven = false;
}
else {
$menuItem = $menu->getItem($query['Itemid']);
$menuItemGiven = true;
}
//print_r($menuItem);
if(isset($query['option'])){
unset($query['option']);
}
if(isset($query['view'])){
$view = $query['view'];
}else{
return $segments;
}
unset($query['view']);
if(isset($query['id'])){
if ($menuItemGiven && isset($menuItem->query['id'])) {
$mCatid = $menuItem->query['id'];
} else {
$mCatid = 0;
}
//echo 'hi';
if(strpos($query['id'], ':') === false) {
$db = JFactory::getDbo();
$aquery = $db->setQuery($db->getQuery(true)
->select('alias')
->from('#__goforms_list')
->where('id='.(int)$query['id'])
);
$alias = $db->loadResult();
$query['id'] = $alias;
}
$segments[] = $query['id'];
unset($query['id']);
}
print_r($segments);
return $segments;
}
function GoFormsParseRoute($segments){
$vars = array();
$app = JFactory::getApplication();
$menu = $app->getMenu();
$item = $menu->getActive();
$params = JComponentHelper::getParams('com_goforms');
$db = JFactory::getDBO();
print_r($item);
$count = count($segments);
if($count == 1){
if(isset($segments[0])){
$vars['view'] = 'region';
$alias = str_replace(':','-',$segments[0]);
//print_r($alias);
//echo '<br>';
$query = 'SELECT alias, id FROM #__goforms_list WHERE alias = "'.$alias.'"';
$db->setQuery($query);
$page = $db->loadObject();
if($page){
$vars['view'] = 'region';
$vars['id'] = (int)$page->id;
return $vars;
}else{
$vars['view'] = 'goforms';
}
}else{
$vars['view'] = 'goforms';
}
}
return $vars;
}
?>
in review:
Joomla 2.5
component is at root menu item of site (home)
items from component need to fall under the first level of menu after home
links work, however JRoute class in joomla does not properly make the link.