Class to display different views for my blog.
class SB_Display {
public function __contruct() {
include_once('settings/db.settings.php');
$mysqli = new mysqli($SB_dbsettings['host'],$SB_dbsettings['user'],$SB_dbsettings['pass'],$SB_dbsettings['dbname']);
}
private function List_Display() {
$VIEW = '';
include_once('views/list.html.view.php');
$sql = "SELECT * FROM sb_posts ORDER BY ID DESC LIMIT '$SETTINGS->maxposts'";
$sql = $mysqli->real_escape_string($sql);
$res = $mysqli->mysqli_query($sql);
if($res->numrows > 0) {
$res->data_seek(0);
while ($row = $res->fetch_assoc()) {
foreach($row as $key => $value) {
$BLOG->$key = $value;
$VIEW .= $HTML;
}
}
} else {
$VIEW .= 'No Posts To Display';
}
return $VIEW;
}
private function Single_Display($id) {
$VIEW = '';
include_once('views/single.html.view.php');
$sql = "SELECT * FROM sb_posts WHERE BID = '$id'";
$sql = $mysqli->real_escape_string($sql);
$res = $mysqli->mysqli_query($sql);
$row = $res->fetch_assoc();
foreach($row as $key => $value) {
$BLOG->$key = $value;
}
$VIEW .= $HTML;
return $VIEW;
}
private function Create_Display() {
include_once('views/create.html.view.php');
return $HTML;
}
private function Edit_Display($id) {
$VIEW = '';
$sql = "SELECT * FROM sb_posts WHERE BID = '$id'";
$sql = $mysqli->real_escape_string($sql);
$res = $mysqli->mysqli_query($sql);
$row = $res->fetch_assoc();
foreach($row as $key => $value) {
$BLOG->$key = $value;
}
$BLOG->id = $id;
$VIEW .= $HTML;
return $VIEW;
}
public function SB_Get_Display($type,$id) {
switch($type) {
case 'list':
$this->content = List_Display();
return $this;
break;
case 'single':
$this->content = Single_Display($id);
return $this;
break;
case 'create':
$this->content = Create_Display();
return $this;
break;
case 'edit':
$this->content = Edit_display($id);
return $this;
break;
}
}
}
When using this class in the following manner ..
$BODY = new SB_Display();
$BODY->SB_Get_Display('list','');
I get this error:
Fatal error: Call to undefined function List_Display()
I can't figure out why. Any help would be greatly appreciated.
You need to use $this->function() instead of function() to call a method.
On a side-note, your constructor function name is incorrect. It's __contruct() but needs to be __construct() to be used as a constructor. Besides that, your indentation is horrible and makes the code hard to read.
I agree with #Corbin, that's a very bad idea. Also, personally, I love the autoload classes approach.
Some might say it's sloppy and the easy way out, but it forces you to really think about your classnames and directories, plus you avoid problems when you're renaming files/ classes. In your case you'd have to search for all files trying to include it and rename everything manually.
"my" approach: create a inc.php or something in the root of your site, and put this in it:
PHP
//autoload classes
function __autoload($class_name){
set_include_path(get_include_path().PATH_SEPARATOR.'/usr/share/file/'); //also
//include magic file location
// put the path to your class files here
$path = $_SERVER['DOCUMENT_ROOT'].'/lib/classes/';
// tell PHP to scan the default include path AND your include path
set_include_path(get_include_path() . PATH_SEPARATOR . $path);
// name your classes and filenames with underscores, i.e., Net_Whois stored in
//Net_Whois.php
$classfile = str_replace("_", DIRECTORY_SEPARATOR, $class_name) . ".php";
require_once($classfile);
}
just initialise your db connections in the inc.php file as well and you can access them pretty much anywhere.
now just include the inc.php file in every new class you create, and you never have to look back again( depending on the project ofcourse)
Related
I'm working on a mvc project just for fun.
Pretty urls already work, but i can't find a good way with my code to send visitors to a 404 page, in case the page doesn't exist which people are looking for.
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;
}
}
public function submit()
{
$uriGetParam = isset($_GET['uri']) ? '/' . $_GET['uri'] : '/';
foreach($this->_uri as $key => $value){
if(preg_match("#^$value$#",$uriGetParam)){
if(is_string($this->_method[$key])){
$useMethod = $this->_method[$key];
new $useMethod();
}
else{
call_user_func($this->_method[$key]);
}
}
}
}
}
I didn't analyze your code thoroughly (I couldn't, not sure what is the example route / method you're adding with ->add), but the solution seems simple to me:
public function submit()
{
$uriGetParam = isset($_GET['uri']) ? '/' . $_GET['uri'] : '/';
$routeFound = false;
foreach($this->_uri as $key => $value){
if(preg_match("#^$value$#",$uriGetParam)){
if(is_string($this->_method[$key])){
$routeFound = true;
$useMethod = $this->_method[$key];
new $useMethod();
}
else{
$routeFound = true;
call_user_func($this->_method[$key]);
}
}
}
if(!$routeFound){
http_response_code(404);
echo 'ooooh, not found';
//or:
include('404.php');
die();
}
}
p.s. http_response_code is a built-in function:
https://secure.php.net/manual/en/function.http-response-code.php
edit: you could put the code starting with 'http_response_code(404);' to a separate function and just call it.
I'm looking for option to make install.php where user puts all needed data e.g. db host, db username, db pwd etc. Script must put it to php class called config.
public function __construct(){
$this->site_address = '';
$this->db_prefix = '';
$this->site_desc = '';
$this->site_title = '';
$this->hash = '';
$this->sidebar = false;
$this->db_host = '';
$this->db_name = '';
$this->db_pass = '';
$this->db_user = '';
$this->db_port = 3306;
$this->folder = NULL;
$this->mailserver = '';
$this->mailport = '';
$this->mailuser = '';
$this->mailpassword ='';
}
How to put data from form on install.php page to this class constructor?
I was thinking about getting content->find $this->db_host = and replace '' for '.$_POST['db_host'].' from form and then put content to file and save, but I don't know how exactly do that. Please help.
Simply add variable to your __construct()
public function __construct($site_address='',$db_prefix='',$site_desc='',$site_title='',$hash='',$sidebar=false){
$this->site_address = $site_address;
$this->db_prefix = $db_prefix;
$this->site_desc = $site_desc;
$this->site_title = $site_title;
$this->hash = $hash;
$this->sidebar = $sidebar;
// And so on
}
Then from your form you do a new yourAwesomeClassName('http://hello','$_POST['db_prefix']',...)
Don't forget few things:
Never trust user input
Sanitize/check all your data/inputed format before using them
Don't save passwords in plain text, at least hash them, better would be using a salt in addition to that of course.
Update according to comment
(The following may not be a good practice but I'm open to suggestions as this is part of my current work)
If you need to save your data I suggest you to have a generic file for example ...
Generic file
Source
class Database
{
/**
* Database host
* #var string Default: 'your-database-host'
*/
const DB_HOST = 'your-database-host';
/**
* Database name
* #var string Default: 'your-database-name'
*/
const DB_NAME = 'your-database-name';
// And so on
}
Then you need a function that writes your data
Write default data
Source
public static function writeDatabaseConfig($data)
{
if (is_array($data)) {
$root = static::getRoot();
$databaseFile = $root . 'App' . DIRECTORY_SEPARATOR . 'Config' . DIRECTORY_SEPARATOR . 'Database.php';
$currentFile = file_get_contents($databaseFile);
if (strpos($currentFile, 'your') !== false) {
$oldToNew = array(
'host' => 'your-database-host',
'name' => 'your-database-name',
);
foreach ($oldToNew as $key => $value) {
if (isset($data[$key])) {
$currentFile = str_replace($value, $data[$key], $currentFile);
}
}
if (file_put_contents($databaseFile, $currentFile)) {
return true;
}
return false;
}
return false;
}
return false;
}
At the end in your __construct() you only need to call writeDatabaseConfig() to write your data. Once done you can get your information by calling ConfigClass::DB_HOST for example ...
Hello I am trying to build my first restful web service and im using the instruction from lorna jane mitchell blog.
If the req comes through this Url : http://localhost:8888/lorna/index.php/tree/getpath?node_id=75
i call the function getpath passing node_id
The function get path looks like this :
class NestedSet
{
public function getPath($id) {
$sql = "SELECT p." . $this->pk . ", p." . $this->name . " FROM ". $this->table . " n, " . $this->table . " p WHERE n.lft BETWEEN p.lft AND p.rgt AND n." . $this->pk ." = " . $id . " ORDER BY p.lft;";
$result = $this->db->query($sql);
if ($result->num_rows == 0) {
return $this->error(1, true);
}
$path = array();
$i = 0;
while ($row = $result->fetch_assoc()) {
$path[$i] = $row;
$i++;
}
return $path;
}
}
Now i want to pass this variable $path to the class JsonView that looks like this :
class JsonView extends ApiView {
public function render($path) {
header('Content-Type: application/json; charset=utf8');
echo json_encode($path);
return true;
}
}
class ApiView {
protected function addCount($data) {
if(!empty($data)) {
// do nothing, this is added earlier
} else {
$data['meta']['count'] = 0;
}
return $data;
}
}
Any Idea on how can I pass the variable $path or any other variable through this JsonView Class.
Thank you very much for your time :)
UPDATE This is the code for creating the nested class object
public function getAction($request) {
$data = $request->parameters;
if(isset($request->url_elements[2])) {
switch ($request->url_elements[2]) {
case 'getpath':
$id = $data['node_id'];
$nested = new NestedSet();
$nested->getPath($id);
$api = new JsonView();
$api->render($path);
break;
default:
# code...
break;
}
} else {
$nested = new NestedSet();
echo $nested->treeAsHtml();
}
}
Just create object of JsonView and then call the function render using that object.
$api = new JsonView;
$api->render($path);
I'm trying to do this:
class database {
function editProvider($post)
{
$sql = "UPDATE tbl SET ";
foreach($post as $key => $val):
if($key != "providerId")
{
$val = formValidate($val);
$sqlE[] = "`$key`='$val'";
}
endforeach;
$sqlE = implode(",", $sqlE);
$where = ' WHERE `id` = \''.$post['id'].'\'';
$sql = $sql . $sqlE . $where;
$query = mysql_query($sql);
if($query){
return true;
}
}
//
}//end class
And then use this function * INSIDE of another class *:
function formValidate($string){
$string = trim($string);
$string = mysql_real_escape_string($string);
return $string;
}
//
.. on $val. Why doesn't this work? if I write in a field of the form, it's not escaping anything at all. How can that be?
* UPDATE *
handler.php:
if(isset($_GET['do'])){
if($_GET['do'] == "addLogin")
{
$addLogin = $db->addLogin($_POST);
}
if($_GET['do'] == "addProvider")
{
$addProvider = $db->addProvider($_POST);
}
if($_GET['do'] == "editProfile")
{
$editProfile = $db->editProfile($_POST);
}
if($_GET['do'] == "editProvider")
{
$editProvider = $db->editProvider($_POST);
}
}
//end if isset get do
** The editProvider function works fine except for this :-) **
You need to instantiate that validate class and than once instantiated you will need to call that function in that class with your value parameters.
Inside your editProvider you can have:
$validator = new validate();
$val = $validator->formValidate($val);
If the above doesn't work, try the following:
$val = mysql_real_escape_string(trim($val));
and see if it works, if it does it has to do with the correct function not being called.
Not sure why you are so bent on using $this vs a static implementation. IMO, a static call makes this code much easier. If you really want access to $this->formValidatString() from your database class, you will have to do class database extends MyOtherClass.
Here is how easy it would be to do a static call:
class database {
public function editProvider($post)
{
$sql = "UPDATE tbl SET ";
foreach($post as $key => $val):
if($key != "providerId")
{
$val = MyOtherClass::formValidate($val);
$sqlE[] = "`$key`='$val'";
}
endforeach;
$sqlE = implode(",", $sqlE);
$where = ' WHERE `id` = \''.$post['id'].'\'';
$sql = $sql . $sqlE . $where;
$query = mysql_query($sql);
if($query){
return true;
}
}
}//end class
class MyOtherClass
{
public static function formValidate($string) {
if (strlen($string) < 1) {
throw new Exception('Invalid $string ' . $string . ');
}
$string = trim($string);
$string = mysql_real_escape_string($string);
return $string;
}
}
You don't need to have an instance for this purpose. Just do validate::formValidate($val);.
I've got some sample code that I'd like to refactor as I need it to work after a record is saved. It currently works after the record is first rendered (using the afterFilter). What it does is render the view that I want with the layout and saves it to a file.
function afterFilter() {
parent::afterFilter();
if($this->params['pass'][0] == 'contact') {
$surrenderOuput = $this->surrender($this->params['pass'][0]);
$path = WWW_ROOT . 'cache' . DS . $this->params['pass'][0] . DS . 'index.html';
$file = new File($path, true);
$file->write($surrenderOuput);
$file->close();
}
}
function surrender($action = null, $layout = null, $file = null) {
$this->beforeRender();
$viewClass = $this->view;
if ($this->view != 'View') {
if (strpos($viewClass, '.') !== false) {
list($plugin, $viewClass) = explode('.', $viewClass);
}
$viewClass = $viewClass . 'View';
App::import('View', $this->view);
}
$this->Component->beforeRender($this);
$this->params['models'] = $this->modelNames;
if (Configure::read() > 2) {
$this->set('cakeDebug', $this);
}
$View =& new $viewClass($this);
if (!empty($this->modelNames)) {
$models = array();
foreach ($this->modelNames as $currentModel) {
if (isset($this->$currentModel) && is_a($this->$currentModel, 'Model')) {
$models[] = Inflector::underscore($currentModel);
}
$isValidModel = (
isset($this->$currentModel) && is_a($this->$currentModel, 'Model') &&
!empty($this->$currentModel->validationErrors)
);
if ($isValidModel) {
$View->validationErrors[Inflector::camelize($currentModel)] =&
$this->$currentModel->validationErrors;
}
}
$models = array_diff(ClassRegistry::keys(), $models);
foreach ($models as $currentModel) {
if (ClassRegistry::isKeySet($currentModel)) {
$currentObject =& ClassRegistry::getObject($currentModel);
if (is_a($currentObject, 'Model') && !empty($currentObject->validationErrors)) {
$View->validationErrors[Inflector::camelize($currentModel)] =&
$currentObject->validationErrors;
}
}
}
}
$this->autoRender = false;
$output = $View->render($action, $layout, $file);
return $output;
}
So I'm basically rendering the view with it's layout, and returning it as output, and saving it to a file. Great. Is there any way to do something similar in a model?
You may consider setting a member variable in your afterSave() in the model and checking that value in your afterFilter() in your controller.
I found this thread while searching for how to render a view from a model. In my case I'm calling a custom method in the model, so this might not work for afterSave(), but if you're calling a custom method you can do it like this:
Controller:
$this->Model->myFunc($this);
Model
public function myFunc($object) {
$object->render();
}
Hopefully that helps someone else who comes across this thread.