i have a website with a dynamic navigational menu. I keep the controller (portuguese) names in a database, together with the translation to english.
I want to know if it is possible to affect the 'route' array at runtime, so it would create those routes and cache it when the page is loaded.
I hope I was clear enough, thanks for the help
You could do this:
Create a table named Routes
--
-- Table structure for table `Routes`
--
CREATE TABLE IF NOT EXISTS `Routes` (
`idRoutes` int(11) NOT NULL AUTO_INCREMENT,
`Order` int(11) NOT NULL,
`Url` varchar(250) NOT NULL,
`Url_Variable` varchar(20) NOT NULL,
`Class` text NOT NULL,
`Method` text NOT NULL,
`Variable` text NOT NULL,
`Date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`idRoutes`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=67 ;
Create a file in the config directory named pdo_db_connect.php
Put this inside and change accordingly.
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
function pdo_connect(){
try{
// Include database info
include 'database.php';
if(!isset($db)){
echo 'Database connection not available!';
exit;
}
$dbdriver = $db['default']['dbdriver'];//'mysql';
$hostname = $db['default']['hostname'];//'localhost';
$database = $db['default']['database'];//'config';
$username = $db['default']['username'];//'root';
$password = $db['default']['password'];//'password';
//to connect
$DB = new PDO($dbdriver.':host='.$hostname.'; dbname='.$database, $username, $password);
return $DB;
}catch(PDOException $e) {
echo 'Please contact Admin: '.$e->getMessage();
}
}
Now in your routes file you can do this:
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
// Include our PDO Connection
include('application/config/pdo_db_connect.php');
class dynamic_route{
public $pdo_db = FALSE;
public function __construct(){
}
private function query_routes(){
try{
$routes_query = $this->pdo_db->query('SELECT * FROM Routes ORDER BY `Order` ASC');
if($routes_query){
$return_data = array();
foreach($routes_query as $row) {
$return_data[] = $row;
}
return $return_data;
}
}catch(PDOException $e) {
echo 'Please contact Admin: '.$e->getMessage();
}
}
private function filter_route_data($data){
$r_data = array();
foreach($data as $row){
$return_data = new stdClass;
if(empty($row['Url_Variable']) ){
$return_data->url = $row['Url'];
}else{
$return_data->url = $row['Url'].'/'.$row['Url_Variable'];
}
if(empty($row['Method']) && empty($row['Variable']) ){
$return_data->route = $row['Class'];
}elseif(!empty($row['Method']) && empty($row['Variable']) ){
$return_data->route = $row['Class'].'/'.$row['Method'];
}elseif(!empty($row['Method']) && !empty($row['Variable']) ){
$return_data->route = $row['Class'].'/'.$row['Method'].'/'.$row['Variable'];
}
$r_data[] = $return_data;
}
return $r_data;
}
public function get_routes(){
$route_data = $this->query_routes();
$return_data = $this->filter_route_data($route_data);
return $return_data;
}
}
$dynamic_route = new dynamic_route;
// Give dynamic route database connection
$dynamic_route->pdo_db = pdo_connect();
// Get the route data
$route_data = $dynamic_route->get_routes();
//Iterate over the routes
foreach($route_data as $row){
$route[$row->url] = $row->route;
}
Remember that the routes file is just a PHP file that contains an array, so if you want to get your "Hacker" t-shirt on you could easily do something a little bit dirty.
Have your CMS/application/web-app/fridge-monitoring-system/whatever to have an interface which creates and stores records in a database. Then whenever you save, throw this content into application/cache/routes.php.
Lastly you just have your main routes.php include the cached version and you're good to go.
Yes you can take a look here:
http://ellislab.com/forums/viewthread/185154/
http://ellislab.com/forums/viewthread/182180/
You need the following.
One controller like this which will save your routes to a file called "routes.php" in the application/cache folder:
public function save_routes()
{
// this simply returns all the pages from my database
$routes = $this->Pages_model->get_all($this->siteid);
// write out the PHP array to the file with help from the file helper
if (!empty($routes)) {
// for every page in the database, get the route using the recursive function - _get_route()
foreach ($routes->result_array() as $route) {
$data[] = '$route["' . $this->_get_route($route['pageid']) . '"] = "' . "pages/index/{$route['pageid']}" . '";';
}
$output = "<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');\n";
$output .= implode("\n", $data);
$this->load->helper('file');
write_file(APPPATH . "cache/routes.php", $output);
}
}
Here's the second function you will need. This one and the one prior will both go in your application controller which handles your pages:
// Credit to http://acairns.co.uk for this simple function he shared with me
// this will return our route based on the 'url' field of the database
// it will also check for parent pages for hierarchical urls
private function _get_route($id)
{
// get the page from the db using it's id
$page = $this->Pages_model->get_page($id);
// if this page has a parent, prefix it with the URL of the parent -- RECURSIVE
if ($page["parentid"] != 0)
$prefix = $this->_get_route($page["parentid"]) . "/" . $page['page_name'];
else
$prefix = $page['page_name'];
return $prefix;
}
In your Pages_model you will need something along this line:
function get_page($pageid) {
$this->db->select('*')
->from('pages')
->where('pageid', $pageid);
$query = $this->db->get();
$row = $query->row_array();
$num = $query->num_rows();
if ($num < 1)
{
return NULL;
} else {
return $row;
}
}
And this:
function get_all($siteid) {
$this->db->select('*')
->from('pages')
->where('siteid', $siteid)
->order_by('rank');
;
$query = $this->db->get();
$row = $query->row_array();
$num = $query->num_rows();
if ($num < 1)
{
return NULL;
} else {
return $query;
}
}
Every time a page is created, you'll need to have this line executed so I suggest putting it at the end of the controller after all the dirty work is done:
$this->save_routes();
All this together will make you a sweet routes file that will be constantly updated whenever things change.
Something not overly complex, and it keeps the URLs friendly:
inside of routes.php:
// Routes from the database
require_once (BASEPATH .'database/DB.php');
$db =& DB();
// slug will be something like
// 'this-is-a-post'
// 'this-is-another-post'
$sql = "SELECT id, slug FROM items";
$query = $db->query($sql);
$result = $query->result();
foreach( $result as $row )
{
// first is if multiple pages
$route["$row->slug/(:num)"] = "item/index/$row->id";
$route["$row->slug"] = "item/index/$row->id";
}
This assumes 'id' as a primary key and that 'slug' will be unique
Inside your controller, you can obtain the id by:
$id = $this->uri->rsegment(3);
Related
I have a system that user can login, and can select the event and will save into the database.
However, the problem is that i can set to only one user, as you can see in line 9 in the save.php
So my question is, how to set the user in the system to be automatic so that if other user login, the data will be save under their name. the problem is because the login is using yii2 framework and this select event is using html and the model of the event is using gii,
Here are my code:
The code for viewevents.php
<?php
echo '<link href="../../css/style.css" rel="stylesheet"/>';
$event = get_events();
function get_events(){
include ("../config/connect.php");
$sql = "SELECT * FROM `events` order by event_id desc;";
if ($result = $dayahlatiff->query($sql)) { $in = 0;
while ($row = $result->fetch_assoc()) {
$new_res[$in] = $row;
$in++;
}
$result->free();
}
return isset($new_res)?$new_res:array();
}
$this->title = 'View Events';
$this->params['breadcrumbs'][] = $this->title;
?>
<?php $in = 1;
if (!empty($event)) {
include 'events.php';
}
?>
The code for save.php
<?php
session_start();
if(isset( $_SESSION["id_"])){
// $hh = $_SESSION["id_"];
// die($hh);
}
require("../../../vendor/yiisoft/yii2/Yii.php");
$user = "dayahlatiff";
//$user = Yii::$app->user->identity->username;
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
if(isset($_POST["save"])){
include ("../../config/connect.php");
$where = $_POST["where"];
$list = $_POST["check_list"];
if(empty($list)){
header("Location: ".$where);
}else {
$done = true;
for($s = 0; $s<sizeof($list); $s++){
$event = $list[$s];
$sql = "INSERT INTO `selectevents` (`user_id`, `username`, `event_title`) VALUES (NULL, '$user', '$event');";
if($dayahlatiff->query($sql) === FALSE){
$event = false;
}
}
header("Location: ".$where);
}
}
I suggest you getting some information about
Object Oriented Programming
MVC structure
Namespacing
Active Record
And getting a little bit familier with yii2 and its documentation.
This code is pure PHP, in frameworks such as Yii2, there is no such things as including files or connecting to databases like that.
Take a close look at Yii2 documentation from This Url and try to code using the concepts available under Yii2 structure. Make sure you get familier with this concepts and try to forget old school native PHP programming.
I am working in CakePHP. I want to save posted data into my database.So I have created function in controller that looks like below :
function add_news()
{
$this->_checkSession();
$this->layout = "admin_inner";
if(!empty($this->params['form']))
{
$tit = $this->params['form']['title'];
$con = $this->params['form']['content'];
$query = "insert into news(news_title,news_content) values('".$tit."','".$con."')";
echo $query;
$this->News->query($query);
}
Configure::write('debug', '2');
}
I print query and execute in database then it works fine.But here it does not execute.I do not have News model.
Note : I am working in CakePHP 1.3.13
first you need to know how to insert data in cakephp ....link for this is :- http://book.cakephp.org/1.3/en/The-Manual/Developing-with-CakePHP/Models.html
then you can try this code to insert data in table
if(!empty($this->params['form']))
{
$tit = $this->params['form']['title'];
$con = $this->params['form']['content'];
$data = array(
"news_title"=>$tit,
"news_content"=>$con
);
$this->News->save($data);
}
function add_news()
{
$this->_checkSession();
$this->layout = "admin_inner";
if(!empty($this->params['form']))
{
$tit = $this->params['form']['title'];
$con = $this->params['form']['content'];
$data = array(
"news_title"=>$tit,
"news_content"=>$con
);
$this->News->save($data);
}
Configure::write('debug', '2');
}
I have retrieved data from DB and inserted into a html table however I want to make each value in the table a hyperlink to another page. Below I have tried making the pupil_id and link to a profile.php but all pupil_id values have now vanished!
(if (!isset($_POST['search'])) {
$pupils = mysql_query("SELECT * FROM pupil") or die("Cant find Pupils");
$count = mysql_num_rows($pupils);
if ($count == 0) {
$totalpupil = "There are currently no Pupils in the system.";
} else {
while ($row = mysql_fetch_array($pupils)) {
?>
<tr>
<td><?php echo '<a href="profile.php?id=' .$row['pupil_id'] . '"</a>' ?></td>
<td><?php echo $row['pupil_name'] ?></td>
<td><?php echo $row['class_id'] ?></td>
</tr>
<?php
}
}
})
The finishing table should display every hyperlink as a hyperlink to another page. Any help?
Because your HTML is invalid, you are missing a closing > and you have no text defined for the hyperlink
<?php echo '<a href="profile.php?id=' .$row['pupil_id'] . '"</a>' ?> //Wrong
Correct would be
<?php echo ''.$row['pupil_id'].''; ?>
Try replace this:
<?php echo '<a href="profile.php?id=' .$row['pupil_id'] . '"</a>' ?>
with this:
<?php echo "<a href='profile.php?id=".$row['pupil_id']."'>link</a>"; ?>
Also, you dont have <table> tags at all.
You don't put any text between your link tags, text here
Maybe this will help you:
<td><?php echo ''.$row['pupil_name'].'' ?></td>
http://uk3.php.net/mysql_query
Watch out, which ever resource you are learning from may well be quite old. mysql_query is now deprecated.
http://uk3.php.net/manual/en/ref.pdo-mysql.php is a replacement.
Here is a kick starter to using PDO (this is much much safer) i write a while ago.
Include this file in which ever php script needs to access your db. An example file name would be 'database.php' but that is your call. Set the namespace from 'yourproject' to whatever your project is called. Correct the database credentials to suit your database
This will save you a lot of headaches hopefully!
I have given some example uses at the bottom for you. I remember when i started out getting clear advice was sometimes hard to come by.
//***** in a database class file*****/
namespace yourproject;
class Database {
private $db_con = '';
/*** Function to login to the database ***/
public function db_login()
{
// Try to connect
try{
// YOUR LOGIN DETAILS:
$db_hostname = 'localhost';
$db_database = 'yourdatabasename';
$db_username = 'yourdatabaseusername';
$db_password = 'yourdatabasepassword';
// Connect to the server and select database
$this->db_con = new \PDO("mysql:host=$db_hostname;dbname=$db_database",
"$db_username",
"$db_password",
array(\PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8"));
// Prevent emulation of prepared statements for security
$this->db_con->setAttribute(\PDO::ATTR_EMULATE_PREPARES, false);
$this->db_con->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
return true;
}
// If it fails, send user to maintenance page
catch(PDOException $e)
{
header("location:http://yourwebsiteurl.com/maintenance.php");
exit();
}
}
/*** Function for database control ***/
public function db_control($query , $parameters, $returnID = false)
{
if(!is_array($query) && is_array($parameters))
{
try{
//prepare the statement
$statement = $this->db_con->prepare($query);
//execute the statement
$statement->execute($parameters);
//check whether this is a select, if it is then we need to retrieve the selected data
if(strpos($query, 'SELECT') !== false)
{
//fetch the results
$result = array();
while( $row = $statement->fetch(\PDO::FETCH_ASSOC) )
{
$result[] = $row;
}
//count the results
$count = count($result);
//return the array
return array( 'results' => $result, 'result_count' => $count );
}
//else return the number of affected rows
else{
//count the affected rows and place into a returnable array
$affected_rows = $statement->rowCount();
$returnArray = array('result_count' => $affected_rows);
//check to see if we are to return a newly inserted autoincrement ID from an INSERT
if($returnID)
{
//find the newly created ID and add this data to the return array
$insertID = $this->db_con->lastInsertId();
$returnArray['ID'] = $insertID;
}
return $returnArray;
}
}
catch(PDOException $e)
{
return false;
}
}
else{
return false;
}
}
}
// Start the database class and connect to the database then create a globally accessible function for ease of reference
$db = new \yourproject\Database();
$db->db_login();
function _db( $sql , $params , $returnID = false ){
return $GLOBALS['db']->db_control( $sql , $params , $returnID );
}
When you include this file you now have a new function: _db(). As the function is global it can be called from within any class or std file. When called into a variable as demonstrated below will result in an array like this:
array(
'result_count' => 3,
'results' => array(
array(/*row 1*/),
array(/*row 2*/),
array(/*row 3*/),
.. etc etc
)
)
Now include your database file in your php script:
//call in the database file
require_once 'database.php';
//your query as in the op
$sql = 'SELECT * FROM pupil';
//your params for the query
$params = array();
//running the query and getting the results returned into a variable called $query
$query = _db($sql,$params);
//if no results
if( $query['result_count'] == 0 )
{
echo 'sorry no pupils in the system';
}
else
{
//looping through each result and printing into a html table row
for( $i = 0 ; $i < $query['result_count'] ; ++$i )
{
echo '<tr><td><a href="profile.php?id=' . $query['results'][$i]['pupil_id'] . '"</a></td>';
echo '<td>'. $query['results'][$i]['pupil_name'] . '</td>';
echo '<td>'. $query['results'][$i]['class_id'] . '</td></tr>';
}
}
Your original query but with some parameters passed through
//Passing parameters to the query
//your query
$sql = 'SELECT * FROM pupil WHERE pupil_id = :pupil_id AND class_id = :class_id';
//your params for the query
$params = array(
':pupil_id' => 12,
':class_id' => 17,
);
//running the query and getting the results returned into a variable called $query
$query = _db($sql,$params);
//deal with the results as normal...
If you set the 3rd param as true you can return the automatic id of the row just entered eg:
//where $sql is a query that will INSERT a row
$query = _db($sql,$params, true);
I have the following variable $user_id being set by
//Check if user is logged in
session_start();
if (!isset ($_SESSION['user_id']))
{
header("location:login.php");
}
elseif(isset ($_SESSION['user_id']))
{
$user_id = $_SESSION['user_id'];
}
and then within the same function file I have the following:
function course_menu()
{
$sqlSubscription = "SELECT * FROM subscriptions WHERE `user_id` = '".$user_id."'";
$subscriptionResult = mysql_query($sqlSubscription);
while ($rows = mysql_fetch_assoc($subscriptionResult))
{
$user_id = $rows['user_id'];
$course_id = $rows['course_id'];
$course_title = $rows['course_title'];
if ($data_id == $rows['course_id'])
{
echo
'<li>
',$course_title,'
</li>';
}
else
{
echo
'<li>',$course_title,' </li>';
}
}
}
The problem is I keep getting undefined variable user_id every time I try to run the function. I can echo $user_id on another page lets say index.php by using require_once function.php and then echo $user_id, but for some reason the function itself can't access it?
I think it might be because it's outside its scope - but if so I'm not entirely sure what to do about it.
My question is, how can I get the function to be able to use the variable $user_id?
EDIT
So I've started doing
$user_id = $_SESSION['user_id'];
global $conn;
$sqlSubscription = "SELECT * FROM subscriptions WHERE `user_id` = '".$user_id."'";
$subscriptionResult = $conn->query($sqlSubscription);
while ($rows = mysqli_fetch_assoc($subscriptionResult))
{
$user_id = $rows['user_id'];
$course_id = $rows['course_id'];
$course_title = $rows['course_title'];
if ($data_id == $rows['course_id'])
{
echo
'<li>
',$course_title,'
</li>';
}
else
{
echo
'<li>',$course_title,' </li>';
}
}
which seems to work fine, but it's a bit tedious to add a new connection each time with a function or set the $user_id manually. Is there any way around this as I have several functions that require a connection to the db to pull data. Is there a better way to structure this type of stuff? I'm not very familiar with OOP but I can try it out if I can get some direction, here's another function that I use (and there are at least another 5-6 that require db connections)
function render_dashboard()
{
$user_id = $_SESSION['user_id'];
global $conn;
//Following brings up the number of subscription days left on the user dashboard
$sqlDate = "SELECT * FROM subscriptions WHERE `user_id` = '".$user_id."'" ;
$date = $conn->query($sqlDate);
while ($daterows = mysqli_fetch_assoc($date))
{
$course_registered = $daterows['course_title'];
$date_time = $daterows['end_date'];
$calculate_remaining = ((strtotime("$date_time")) - time())/86400;
$round_remaining = round("$calculate_remaining", 0, PHP_ROUND_HALF_UP);
// Here we assign the right term to the amount of time remaining I.E DAY/DAYS/EXPIRED
if($round_remaining > 1)
{
$remaining = $course_registered." ".$round_remaining." "."Days Remaining";
$subscriptionStatus = 2;
echo '<p>',$remaining,'</p>';
}
elseif ($round_remaining == 1)
{
$remaining = $course_registered." ".$round_remaining." "."Day Remaining";
$subscriptionStatus = 1;
echo '<p>',$remaining,'</p>';
}
elseif ($round_remaining <= 0)
{
$remaining = $course_registered." "."Expired"." ".$date_time;
$subscriptionStatus = 0;
echo '<p>',$remaining,'</p>';
}
}
//Check for most recent viewed video
$sqlVideo = "SELECT `last_video` FROM users WHERE `user_id` = '".$user_id."'" ;
$videoResult = $conn->query($sqlVideo);
if ($videoRows = mysqli_fetch_assoc($videoResult))
{
$last_video = $videoRows['last_video'];
$videoLink = "SELECT `chapter_id` FROM chapters WHERE `chapter_title` = '".$last_video."'";
if ($chapteridResult = mysql_fetch_assoc(mysql_query($videoLink)));
{
$chapter_id = $chapteridResult['chapter_id'];
}
$videoLink = "SELECT `course_id` FROM chapters WHERE `chapter_title` = '".$last_video."'";
if ($courseResult = mysql_fetch_assoc(mysql_query($videoLink)));
{
$course_id = $courseResult['course_id'];
}
}
}
The function course_menu() will not recognize your $user_id, Since it is outside its scope.
Make use of global keyword to solve this issue.
function course_menu()
{
global $user_id;
// your remaining code .........
The solution to getting around it without using global is to either DEFINE and pass it through ie - define ('var', '$var') then function x($var) or dependency injection as stated here How can I use "Dependency Injection" in simple php functions, and should I bother?
I have a nice page including system here is the code for it
if(isset($HTTP_GET_VARS['mod']))
{
$page = $HTTP_GET_VARS['mod'];
}
else
{
$page = 'home';
}
switch($page)
{
case 'home':
require('home.php');
break;
default:
echo('Error: There is no file on this server with that name');
}
}
I am trying to get the case, require from a DB called pages there are 2 fields Name, Link i am trying to get all of the results from the table so it will display the pages
It's not particularly clear from your question, but my reading of it is that you want a way to check any value of $page against a link value in a db table (pages?), without having to write all possible values in to your switch statement,
If my understanding is correct, then the below is a quick-and-dirty function which should let you do this. In a live, heavily-trafficed environment you'd obviously need to build in caching so every page load doesn't hit the db, and strong input validation, neither of which are in the demo below, but this should at least give you an idea of where to go next.
Common library file:
/**
* Given a page name, see if we have an associated
* link in the db.
* If so, return the link value, else false
*/
function getTemplate($page)
{
// Check db to see if we have a link for this page
// On heavy-traffic sites, this should be cached out
$query = sprintf("SELECT link FROM pages WHERE name = '%s'",
mysql_real_escape_string($page));
$result = mysql_query($query, $db_cnx);
// Have we any results?
if (mysql_num_rows($result) > 0)
{
// Assumption: 'name' is unique in the db
$row = mysql_fetch_assoc($result);
return $row['link'];
}
else
{
return false;
}
}
Header.php:
include('common.lib.php');
if(isset($HTTP_GET_VARS['mod']))
{
$page = $HTTP_GET_VARS['mod'];
}
else
{
$page = 'home';
}
// Check whether our page has a link in the db
$template = get_template($page);
if($template)
{
require( $template );
}
else
{
// Got false back from get_template, no link found
echo('Error: There is no file on this server with that name');
}
$server_db = "YOUR_SERVER_DB";
$user_db = "YOUR_USER_DB";
$password_db = "YOUR_PASSWORD_DB";
$db_name = "YOUR_DB_NAME";
$table = "YOUR_TABLE_NAME";
$link = mysql_connect($server_db,$user_db,$password_db);
if (!$link) {
die('Could not connect: ' . mysql_error());
}
mysql_select_db($db_name);
$sql = sprintf("select Name, Link from %s",$table);
$rs = mysql_query($sql,$link);
while($row = mysql_fetch_assoc($rs)) {
echo "<a href='".$row['Link']."'>".$row['Name']."</a>";
}
mysql_free_result($rs);
mysql_close($link);