Can't create TPL Function from PHP Code using Smarty - php

I have created a function to run an SQL query, output the data and that seems fine, Problem is I can't do anything with it now since i can't make the output to the templates work.
PHP Code:
function getCategories() {
try {
foreach($this->pdo->query("SELECT categories.cat_id, categories.cat_name, categories.cat_description FROM categories") as $row) {
$rows[] = $row;
}
} catch(PDOException $e) {
print "Error!:" . $e->getMessage();
return false;
}
return $rows;
$smarty = new Smarty();
$smarty->assign('categories', $rows);
}
Which simply returns this:
Replacing return $rows; with return $smarty->assign('categories', $rows); simply renders a blank page.
I'm using this in the template: {$categories.cat_name}
Can anyone help me fix this?
I'm trying to rewrite a vulnerable crappy forum script using Smarty so it's a base worth trying to develop a script off of. It's literally just categories, topics and a login / register system atm that I'm trying to rewrite using Smarty.

The problem is that you create a new smarty object, assign it a variable, but doesn't use it to display your template - so this object get lost.
I suggest to pass the Smarty object to your function like this:
function getCategories(&$smarty) {
$rows = array();
if($result = $this->pdo->query("SELECT categories.cat_id, categories.cat_name, categories.cat_description FROM categories")) {
$rows = $result->fetchAll();
}
$smarty->assign('categories', $rows);
}
This way the object reference will be passed to the function - you will be able to assign any vars you want to it without the need of returning it. Just be sure that you send the Smarty object you use to render the template.

Related

CakePHP - JsonView rendering is sub function of the controller

I'm using Cakephp with json parse extension and the RequestHandler component in order to create Web services using json.
I created a controller named Ws
In this controller I have a named userSubscribe
In order to avoid a lot of If else statements in the next methods, I thought about using a private function inside this controller that will check somes conditions and stop the script normaly BUT ALSO render the json normaly. I just want to do a DRY way !
My question is :
How could I render the json view in a sub function (called by the userSubscribe) ?
To make it clear, here is the style code that would like
public function userSubscribe() {
$this->check();
// Following code only executed if check didn't render the json view
// $data = ...
$code = 1;
$i = 2;
}
private function check() {
$input = &$this->request->data;
if ($_SERVER["CONTENT_TYPE"] != "application/json") { // For example
$result = "KO";
$this->set(compact("result"));
$this->set('_serialize', 'result');
$this->render(); // HERE, it will stop the 'normal behaviour' and render the json with _serialize
}
if (!isset($input["input"])) {
$result = "KO";
$this->set(compact("result"));
$this->set('_serialize', 'result');
$this->render(); // HERE, it will stop the 'normal behaviour' and render the json with _serialize
}
}
It's seems to be quite simple to do, but why can't I find the answer ?!
Thanks in advance for clue/advise/anything !

How to Test cakephp parseExtension?

I setup the parseExtension for json in my cakephp 2.3.0. No errors are display. It works?
How can I test is?
In RoR ist ist very easy to test via
https://mydomain.de/view/4.json
How does it run on cakephp?
My View-Action is this.
public function view($id = null) {
if (!$this->Atla->exists($id)) {
throw new NotFoundException(__('Invalid atla'));
}
$options = array('conditions' => array('Atla.' . $this->Atla->primaryKey => $id));
$this->set('atla', $this->Atla->find('first', $options));
$this->Atla->id = $id;
$result = $this->Atla->read();
$this->response->type('json');
$this->response->body(json_encode($result));
return $this->response;
$this->set(compact('atlas'));
}
Why i always get an json-request?
If you use the _serialize key cakephp can automatically create json and xml views for you. I typically use the following to create json or xml views:
public function view() {
// data I want to display
$record1 = $this->ModelName->find('first', ...);
$this->set('record1', $record1);
$record2 = $this->ModelName->find('first', ...);
$this->set('record2', $record2);
// option 1: serialize the hard way
$this->set('_serialize', array('record1', 'record2'));
// option 2: serialize the easy way
$this->set('_serialize', array_keys($this->viewVars));
}
PS: the code after your return statement will never be executed.
you'll have create the view
app/View/Atlas/json/view.ctp
which is the view that is being used for .json requests.
Requests without .json will use the regular view file:
app/View/Atlas/view.ctp
There's more information on creating/using JSON and XML views here:
http://book.cakephp.org/2.0/en/views/json-and-xml-views.html#using-a-data-view-with-view-files
From that page the view.ctp may contain something like;
// View code - app/View/Posts/json/index.ctp
foreach ($posts as &$post) {
unset($post['Post']['generated_html']);
}
echo json_encode(compact('posts', 'comments'));
However, it really depends on what you're trying to achieve. If you will only use the 'Atlas/view' action for JSON responses, and won't be using HTML at all, sometimes you can get away with generating the response-body inside your Controller. Not very much 'in line' with MVC conventions, but it saves you from creating a view that does nothing more than echo json_encode($data); ;)
public function view($id)
{
$this->MyModel->id = $id;
$result = $this->MyModel->read();
$this->response->type('json');
$this->response->body(json_encode($result));
//Return reponse object to prevent controller from trying to render a view
return $this->response;
}
If you do want to use both 'HTML' and 'JSON', depending on the request (with/without .json extension), you should have two view files; 1 for JSON and 1 for HTML;
// This view will be used for your JSON requests
app/View/Atlas/json/view.ctp
// This view will be used for non-JSON (html) requests:
app/View/Atlas/view.ctp
In the json-view, output the data using json_encode(.....);
In the 'normal'/html view, just output normal data
In your controller, set the data as normal
public function view($id = null) {
$this->Atla->id = $id;
if (!$this->Atla->exists()) {
throw new NotFoundException(__('Invalid atla'));
}
$this->set('atla', $this->Atla->read());
}

php return mysql_query

How is it possible to retrieve the mysql_query from a function? For instance:
class A() {
...
function getAll($l=1) {
...
$result = mysql_query($query);
return $result
}
...
}
$a = new A();
$r = $a -> getAll(2);
while ($row = mysql_fetch_assoc($r)) {
// do something
}
This code above does not work when I return $result from the function. However, when I use the mysql_fetch_assoc function in getAll function, it works perfectly. So basically, my question is how to return a mysql result set from a function?
** EDIT **
I actually get no errors. The while statement used liked above will just not execute. But the query works perfectly when I execute it from within the getAll function.
Don't return the result resource from the query, but rather return the data extracted from that resource:
$data = array();
while ( $row = mysql_fetch_assoc($result) ) {
$data[] = $row;
}
return $data;
Absolutely it works.
Do a var_dump($r) to make sure you're getting a resource. If not, double-check your SQL. There may be an error in it.
Also turn on other error reporting at the top of your script (as well as checking mysql_error) for better clues as to what's wrong:
ini_set('display_errors', true);
error_reporting(E_ALL);
You've edited much of your code so it's difficult to investigate further. Just make sure that your method is not closing the mysql connection.

Creating a PHP registration class + templating system?

As of right now I've created a template class, and I've created a registration class. But I'm having trouble getting the two to work properly together so that I can display my variables in my template files.
Here are the basics of my template class:
class siteTemplate {
function getTemplate($file, $varesc=false) {
if (file_exists("templates/" . $file)) {
$data = file_get_contents("templates/" . $file);
$data = str_replace("\"","\\\"", $data);
$data = str_replace("\'","\\\'", $data);
$data = str_replace("\\n","\\\n", $data);
if($varesc)
$data = str_replace("\$","$", $data);
return $data;
} else {
die("Error.<br />Could not find <strong>" . $file . "</strong>.");
}
}
function createGlobal() {
global $siteName, $siteUrl;
global $content;
eval("\$main = \"".$this->getTemplate("main.html")."\";");
echo $main;
}
}
$tp = new siteTemplate();
A function from my registration class:
public function get_username($uid) {
$result = mysql_query("SELECT username FROM users WHERE uid = $uid");
$user_data = mysql_fetch_array($result);
echo $user_data['username'];
}
I can echo out data from my registration class in index.php
echo $user->get_username($uid);
BUT I can't do the same thing within my template files. What adjustments do I need to make to make this work together. Live example: http://www.aarongoff.com/i
Username: test
Password: test
If you look I'm echoing out "Logged in as: test"
But when I try to call for that variable within my template file it just displays "Logged in as:"
(I know there are SQL vulnerabilities, I'm just testing to get my classes to work)
The true answer to this is that PHP IS a template! Use pure PHP code as your templates. Then you don't have to keep reimplementing every one of PHP's features in your ad hock template class.
This is called the http://en.wikipedia.org/wiki/Inner-platform_effect and you should avoid it. Just use PHP directly, it's what it was made for.
What you should do is be disciplined about naming the PHP files, and separating concepts logically. But don't try to reimplement PHP in PHP.

PHP OOP function won't grab data unless another function is called

I'm having this weird problem right now, I'm just working on a small admin backend thing that will allow users to upload a file and download it again, simple stuff.
I'm using PHP OOP with Classes and functions and things. Still pretty new at it. Currently on one page I have a "getRecentLinks" function that will call information from a couple tables and put it all out on the page in a table, it works just fine. One of the options on this page is to download the file that was uploaded to that individual row. So I just want it to be a link you click on to say, file-download.php?id=3.
Now on file-download.php I'm currently just testing to get the information on the page before I add the headers and things in there. So I just have a simple
$l = new Links();
$file = $l->getFileInfo($_GET['id']);
print_r($file);
this SHOULD just return information from the database, id, name of file, size, data, and mimetype.
Now this doesn't work. I have no idea why but it doesn't.
Now on my page where I have the getRecentLinks() function it works just fine. I even brought in the getRecentLinks() into my file-download.php page so it's setup like this.
$l = new Links();
$l->getRecentLinks();
$file = $l->getFileInfo($_GET['id']);
print_r($file);
This works just fine and dandy, The second I remove getRecentLinks() it stops calling information from getFileInfo() and I cannot figure it out. I mean it's not a huge deal i could just keep #l->getRecentLinks() there but I can see this getting annoying if I have to add it to every page I want to do something, I'm just at the start of this project.
Here's the code in the Links class
public function getFileInfo($id)
{
$result = $this->runQuery("SELECT * FROM file WHERE id ='".mysql_real_escape_string($id)."'");
$resultSet = $this->fetch($result);
return $resultSet;
}
and
public function getRecentLinks()
{
$result = $this->runQuery("SELECT * FROM links ORDER BY date DESC");
while($j = $this->fetch($result))
{
$resultSet[] = $j;
}
return $resultSet;
}
And heres my connections and fetch functions a friend helped me develop
public function runQuery($sql) {
$this->connection = mysql_connect($this->dbhost, $this->dbuser, $this->dbpass);
if(!$this->connection) {
die("MySQL is down.");
} else {
mysql_select_db($this->dbname);
}
$result = mysql_query($sql,$this->connection) or die(mysql_error());
return $result;
}
public function fetch($result)
{
$resultSet = mysql_fetch_assoc($result);
return $resultSet;
}
mysql_real_escape_string requires a connection. Since getRecentLinks opens a connection it works. But you call mysql_real_escape_string before runQuery (in execution order) in getFileInfo. In this case, I assume the id is an integer, so you're better off and a lot cheaper to call intval($_GET['id']).

Categories