working with smarty and mysql database? - php

this is the first time that I need to work with smarty and it seems quite straight forward.
however, there is twist in my PHP code and that is causing an issue.
here is what I am trying to do:
Before you start beating me for not using mysqli functions etc, please note that this code is just a simple test for me to understand the smarty first. so i won't be using mysql in my project and I do not recommend anyone to do so...
any way, here is what I am trying to do:
I am using the following code in my index.php page:
<?php
header("Content-type: text/html; charset=utf-8");
function isSubdomain()
{
$host = $_SERVER['HTTP_HOST'];
$host = explode('.',$host);
$host = (is_array($host)?$host[0]:$host);
return $host;
}
?>
<?php
// These are the smarty files
require 'libs/Smarty.class.php';
// This is a file which abstracts the DB connecting functionality (Check out PEAR)
include "config/connect_to_mysql.php";
$smarty = new Smarty;
$smarty->compile_check = true;
$smarty->debugging = false;
$smarty->use_sub_dirs = false;
$smarty->caching = true;
// This SQL statement will get the 5 most recently added new items from the database
$storeShop = isSubdomain();
echo $storeShop;
$sql = 'SELECT * ';
$sql .= 'FROM $storeShop ';
$sql .= 'ORDER BY `id` ';
$result = mysql_query($sql) or die("Query failed : " . mysql_error());
// For each result that we got from the Database
while ($line = mysql_fetch_assoc($result))
{
$value[] = $line;
}
// Assign this array to smarty...
$smarty->assign('storeShop', $value);
// Assign this array to smarty...
$smarty->assign('$storeShop', $value);
// Display the news page through the news template
$smarty->display('index.tpl');
// Thanks to David C James for a code improvement :)
?>
and this is the index.tpl file:
<!-- This is the DOC type declaration and links in the CSS stylesheet etc -->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<meta http-equiv="content-type" content="application/xhtml+xml; charset=utf-8" />
<meta name="author" content="Steve Rendell" />
<meta name="generator" content="EditPlus" />
<link rel="stylesheet" type="text/css" href="style.css" title="Default CSS Sheet" />
<title>News Page</title>
</head>
<body id="top">
<!-- OK display the page header to keep it nice-->
<div id="header">
<span>Steve's News Page</span>
</div>
<!-- This is where the news article will be going -->
<div id="bodyText">
<!-- Have a title -->
<h1 id="welcome">Read All About It</h1>
<!-- OK this is a section which will loop round for every item in $news (passed in through from PHP) -->
{section name=storeShop loop=$storeShop}
<!-- For every item, display the Title -->
<h2 id="{$storeShop[$storeShop].id}">{$storeShop[storeShop].product_name}</h2>
<!-- Write out the Author information and the date -->
<h3>{$storeShop[storeShop].price}, {$storeShop[storeShop].details}</h3>
<!-- Now show the news article -->
{$storeShop[storeShop].details}
{/section}
</div>
<!-- Show copyright information etc -->
<div id="footer">All Contents Copy Written :)</div>
<!-- Close the html tags -->
</body>
</html>
when I run the index.php in my browser, I get the following error:
Query failed : Table 'mrshoppc_mainly.$storeShop' doesn't exist
But when I use the following code, I get the right output which is the name of the subdomain and the name of the table in mysql database as well:
$storeShop = isSubdomain();
echo $storeShop;
and I know the table exist. P.S. the table name $storeShop is dynamic, so it could be any name that user chooses and it will be created in the mysql database.
I hope I explained it good enough for someone to be able to help me.
Could someone please tell me why I get the mentioned error and how to solve it?
I suspect this is caused by smarty as I never used to get this error before I started using smarty.
Thanks in advance.

You are not parsing your string that contains the PHP variable.
$sql .= 'FROM $storeShop ';
To PHP single-quoted stings ' ' are literally what you have between the quotes.
" " Double quoted string will be Interpreted by PHP.
Try this:
$sql .= "FROM $storeShop "; // OR
$sql .= 'From '. $storeShop .' ';
PHP Strings

mis been a long time since i used smarty but from what i remeber there is no such thoing as:
{$storeShop[$storeShop].id}
you could use however:{$storeShop.$another_storeShop.id}
if $storeshop is like array('storeshop_key'=>array('id'->'id'))
also $smarty->assign('$storeShop', $value); will create variable $$storeShop which is not correct
tips: print arrays in php before sending to smarty var_dump($value) and then in smarty use {$storeShop|#print_r} to make sure everything is right

just remove
$smarty->assign('$storeShop', $value);
from your PHP code

Related

How can i write a Template of HTML and create that HTML file with custom usernames as files_names when the API endpoints are hit in PHP?

So basically i need that when user registers in my Android App i will make a POST request with user Name and company Name that they wanted and i will create a html page with that data in the HTML Template. and webpage will be visible like this -> www.main-website.com/username [main-website.com is the domain that i have bought]
So what I did , is that I created a variable that stores the HTML Template with custom changes by adding php variables in-between.And then created a file.html. Check this code {and also If you know a better way to do this thing pls suggest [main idea -> userAuthenticate -> webpage created with username and company name as tags (this is protoype) ]
<!DOCTYPE HTML>
<?php
if(isset($_POST['userName']) && isset($_POST['companyName'])){
$user_name = $_POST['userName'];
$company_name = $_POST['companyName'];
}
$my_var = <<<EOD
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>template</title>
</head>
<body>
<h1>This is $user_name </h1>
<h2>My company name is $company_name </h2>
</body>
</html>
EOD;
$fp = fopen($_SERVER['DOCUMENT_ROOT'] . "/myText.php","wb");
fwrite($fp,$my_var);
fclose($fp);
?>

Forwarding tags like {blabla} to php functions

I saw this in most of CMS and forum templates. How can I make HTML tags like {blabla} and how can I forward them to PHP functions?
These are called templating systems and the style of these "tags" depends on the templating system you're using.
A basic example in PHP would be something like this:
page.tpl:
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Basic templating system</title>
</head>
<body>
<h2>Welcome to our website, {{name}} !</h2>
<p>Please confirm your account. We've sent an email to: {{email}}</p>
</body>
</html>
index.php:
<?php
// Get the template's content
$template = file_get_contents("page.tpl");
// The data needed in the template
$data = array(
'name' => 'John',
'email' => 'john#smith.com',
);
// The template's tags pattern
$pattern = '{{%s}}';
// Preparing the $map array used to replace the template's tags with data values
$map = array();
foreach($data as $var => $value)
{
$map[sprintf($pattern, $var)] = $value;
}
// Replace the tags with data values
$output = strtr($template, $map);
// Output the template with replaced tags
echo $output;
?>
I recommend that you check out already existing templating engines such as: Mustache, Smarty or Twig and many others
Hope this helps :) !

Ajax save function to server doesn't work correctly

I'm working on a website that let's users simply save a note, to be accessed later. I'm however having quite some trouble with actually saving the note. I first had it set to automatically save on each keypress, but it's better if I have the user press on a button to save the file. What you'll also see in the code is that the note gets saved as the users IP address, when the user then visits the site again he'll see the same note (if he has the same IP again).
The error I get now when clicking the save button is:
PHP Warning: file_put_contents() [<a href='function.file-put-contents'>function.file-put-contents</a>]: Filename cannot be empty in /home/martmart/public_html/index.php on line 41
My index.php:
<?php
$note_name = 'note.txt';
$uniqueNotePerIP = true;
if($uniqueNotePerIP){
// Use the user's IP as the name of the note.
// This is useful when you have many people
// using the app simultaneously.
if(isset($_SERVER['HTTP_X_FORWARDED_FOR'])){
$note_name = 'notes/'.$_SERVER['HTTP_X_FORWARDED_FOR'].'.txt';
}
else{
$note_name = 'notes/'.$_SERVER['REMOTE_ADDR'].'.txt';
}
}
if(isset($_SERVER['HTTP_X_REQUESTED_WITH'])){
// This is an AJAX request
if(isset($_POST['note'])){
// Write the file to disk
file_put_contents($note_name, $_POST['note']);
echo '{"saved":1}';
}
exit;
}
$note_content = 'Write something here :D';
if(file_exists($note_name) ){
$note_content = htmlspecialchars( file_get_contents($note_name) );
}
function saveNow() {
// Write the file to disk
file_put_contents($note_name, $_GET['note']);
echo '{"saved":1}';
}
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Marty Testweb</title>
<!-- Our stylesheet -->
<link rel="stylesheet" href="assets/css/styles.css" />
<!-- A custom google handwriting font -->
<link rel="stylesheet" href="http://fonts.googleapis.com/css?family=Courgette" />
<!--[if lt IE 9]>
<script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<script src="assets/audiojs/audio.min.js"></script>
<script>
audiojs.events.ready(function() {
var as = audiojs.createAll();
});
</script>
</head>
<body>
<div id="pad">
<h2>Note</h2>
<textarea id="note"><?php echo $note_content ?></textarea>
</div>
<!-- Initialise scripts. -->
<script>
function saveNow()
{
alert("<?php saveNow(); ?>");
}
</script>
<button id="save" onclick="saveNow()">Save Note</button>
<!-- JavaScript includes. -->
<script src="http://code.jquery.com/jquery-latest.min.js"></script>
<script type="text/javascript" src="assets/js/script.js"></script>
</body>
<div id="footer">
<footer>
<a href="">
<div id="footer_right">
Version 0.1.2
</div id="footer_right">
</a>
<audio src="assets/audiojs/music.mp3" preload="auto"></audio>
<div id="footer_left">
Save function not working yet
</div id="footer_left">
</footer>
</div id="footer">
</html>
The script.js:
$(function(){
var note = $('#note');
var saveTimer,
lineHeight = parseInt(note.css('line-height')),
minHeight = parseInt(note.css('min-height')),
lastHeight = minHeight,
newHeight = 0,
newLines = 0;
var countLinesRegex = new RegExp('\n','g');
// The input event is triggered on key press-es,
// cut/paste and even on undo/redo.
note.on('input',function(e){
// Count the number of new lines
newLines = note.val().match(countLinesRegex);
if(!newLines){
newLines = [];
}
// Increase the height of the note (if needed)
newHeight = Math.max((newLines.length + 1)*lineHeight, minHeight);
// This will increase/decrease the height only once per change
if(newHeight != lastHeight){
note.height(newHeight);
lastHeight = newHeight;
}
}).trigger('input'); // This line will resize the note on page load
function ajaxSaveNote(){
// Trigger an AJAX POST request to save the note
$.post('index.php', { 'note' : note.val() });
}
});
I don't really know how to solve this, so any help is greatly appreciated. I just want to have the file save with the same name as the user's IP address, when he click on the button. Please keep in mind I'm still a big newbie with these more advanced features so please point out anything I did wrong (but also please explain it easy :) ).
Thanks for reading,
Mart.
First of all I would suggest considering whether having the filename be the IP address is a good idea...many workplaces and other group settings share the same IP address, so any user at a workplace like that would see the note left by any other user at the same workplace.
As to your error, I think the problem may be that you didn't declare $note_name as a global variable within your function. Try changing it to this:
function saveNow() {
global $note_name;
// Write the file to disk
file_put_contents($note_name, $_GET['note']);
echo '{"saved":1}';
}
In PHP if you want to use a global variable (one that wasn't declared inside a function or class) within a function, you always have to use the global keyword as shown above. Using global variables can be avoided entirely if you structure your code a bit differently, but that's another topic.
I wonder why you didn't get a notice about it not being defined though...while you're still developing you might want to put this at the top of your code:
error_reporting(E_ALL);
P.S. Although your code will work without doing this, for security reasons it would be good to specify the JSON MIME type before outputting JSON from PHP, e.g.:
function saveNow() {
global $note_name;
// Write the file to disk
file_put_contents($note_name, $_GET['note']);
header('Content-type: application/json');
echo '{"saved":1}';
exit;
}

Echo Page Title in PHP

The script below echos the array and its individual elements fine but when the array elements are used to set the page title by running the script after the opening head tag, I still get "untitled document" as the page title.
Further if I try echoing $title alone and placing the title tags <> before and after the php tags, the title is set as the document type definition..
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
It seems that echo sets the relevant HTML tags required before if not already set. Whats the work around ??
<?php
include 'contentStream.php' ;
$upc = $_GET['upc'];
if (isset($upc))
{
global $upc ;
$query = "SELECT * FROM tracks WHERE album_upc='$upc'";
connect();
$db = mysql_select_db("XXXXX");
$results = mysql_query($query, $connection) ;
$result = mysql_fetch_assoc($results);
$title = $result['title']." by ".$result['author'] ;
echo "<title>".$title."</title>";
unset($results);
unset($query);
mysql_close($connection) ;
}
else
{
echo "<title> MYsUPERsITe </title> " ;
}
?>
Is this being executed within the <head> element? If not it needs to be.
I am not sure what contentstream.php is but it looks like you might be running this at the wrong location in the page.
Also try changing $title to $myTitle to see if $title has been set somewhere else.
Your problem seems to be that you are trying to change the contents of the <title> tag after it has already been produced by the non-PHP section of your page. That approach does not work in a server-side environment like PHP.
One solution is to use PHP to generate the entire HTML page, store it in a variable, and just echo() it out when you're all done.
At the top of your page, I would run and parse a database query and build a $html string to echo out later. Multiple echo() statements like you have above can get ugly, and can give you issues with headers and such if you later end up adding cookies or session variables to your site:
<?php
include ("my_cool_lib.php");
$html = "<!DOCTYPE html>";
$html .= "<html><head>";
$db = connect_to_db();
$resultset = run_a_query($db);
$title = get_title($resultset);
$html .= "<title>$title</title>";
$html .= "</head><body>";
$html .= "<h1>Results</h1>";
// loop through $resultset
// $html .= track info
// end loop
$html .= "</body></html>";
echo $html;
?>
You need to set the relevent HTML tags that you're currently missing.
<html>
<head>
<title>Your title</title>
</head>
<body>
body stuff
</body>
</html>

How to echo an PHP tag?

I'm trying to echo a PHP tag by doing this:
echo "<?php echo \"test\"; ?>";
The result should be just "test" without quotes, but my code isn't working. What is happening is that nothing is shown on the page, but the source code is "<?php echo "teste"; ?>"
Most of you will want to know why I want to do this. I'm trying to make my own template system; the simplest way is just using file_get_contents and replacing what I want with str_replace and then using echo.
The problem is, that in the template file, I have to have some PHP functions that doesn't work when I echo the page, is there another simple way to do this? Or if you just answer my question will help a lot!
Here is an example of what I am trying to accomplish:
template.tpl:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>[__TITULO__]</title>
</head>
<body >
<p>Nome: [__NOME__] <br />
Email: [__EMAIL__]<br />
<?php
if ($cidade != "") {?>
Cidade: [__CIDADE__]<br />
<?php
}
?>
Telefone: ([__DDD__]) [__TELEFONE__] <br />
Fax:
([__DDDFAX__]) [__FAX__] <br />
Interesse: [__INTERESSE__]<br />
Mensagem:
[__MENSAGEM__] </p>
</body>
</html>
index.php
<?php
$cidade = "Teste";
$file = file_get_contents('template.php');
$file = str_replace("[__TITULO__]","Esse Título é téste!", $file);
$file = str_replace("[__NOME__]","Cárlos", $file);
$file = str_replace("[__EMAIL__]","moura.kadu#gmail.com", $file);
if ($cidade != "") {
$file = str_replace("[__CIDADE__]",$cidade, $file);
}
echo $file;
?>
I can solve all this just not showing the div that has no content. like if i have a template, and in it i have 2 divs:
<div id="content1">[__content1__]</div>
<div id="content2">[__content2__]</div>
if the time that i set the content to replace the template I set the content1 and not set content 2 the div content2 will not show...
Use htmlspecialchars
That will convert the < > to < and >
You are dealing with two sets of source code here that should never be confused - the server code (PHP, which is whatever is in the <?php ?> tags) and the client (or browser) code which includes all HTML tags. The output of the server code is itself code that gets sent to the browser. Here you are in fact successfully echoing a PHP tag, but it is meaningless to the browser, which is why the browser ignores it and doesn't show anything unless you look at the client code that got sent to it.
To implement templates in this style, either they should not have any PHP code, or the resulting string (which you have stored in $file) should itself be executed as though it were PHP, rather than echoing it straight to the client. There are various ways to do this. One is to parse out the PHP tags in the string, echo everything that is not within the PHP tags and run eval() on everything that is.

Categories