How to include some php class to Joomla tmpls - php

I need to include some php code that must be repeated in many tmpls. How can I do this, may be as class including? And how can I write php file with my class in a right way? In other words I need something like
views/category/tpml/default.php
JLoader::register('MyClass', '/administrator/components/com_mycom/helpers/myclass.php');
$repeatedcode = new MyClass();
echo $resultstr;
views/article/tpml/default.php
JLoader::register('MyClass', '/administrator/components/com_mycom/helpers/myclass.php');
$repeatedcode = new MyClass();
echo $resultstr;
myclass.php
class MyClass {
// some code with string for echo in the end
$resultstr = ...
}
...
UPDATE: #Guilherme thank you! So now it's looking as
The file /mytemplate/html/com_content/article/default.php:
require_once '/administrator/components/com_mycom/helpers/myclass.php';
MyComHelper::myFunction($param);
$newstring = str_replace($find, $replace, $this->item->text);
echo $newstring;
The file administrator/components/com_mycom/helpers/myclass.php:
defined('_JEXEC') or die;
abstract class MyComHelper
{
public static function myFunction($param)
{
$db = &JFactory::getDBO();
$query = $db->getQuery(true);
$query->select($db->quoteName(array('ua', 'ru')))
->from($db->quoteName('#__words'));
$db->setQuery($query);
$results = $db->loadAssocList();
$find = array();
$replace = array();
foreach ($results as $row) {
$find[] = $row['ua'];
$replace[] = $row['ru'];
}
return $find;
return $replace;
}
}
This script replaces every ua words with matched ru words that are stored in my database and it works if I add the script to tmpl directly. But in the case with including when I open a page with an article I see the blank page which contains only a heading and nothing else i.e. content isn't displayed. Maybe a problem with array?

After include the php function in your Helper, you can include it on the tmpl with the require_once
require_once JPATH_COMPONENT.'/helpers/mycom.php';
MycomHelper::myFunction($param);
MycomHelper is the class name of my Helper
com_mycom/helpers/helper.php
<?php
// no direct access
defined('_JEXEC') or die;
// Component Helper
jimport('joomla.application.component.helper');
class MycomHelper
{
public static function dosomething($var)
{
return "Helper say: ".$var;
}
}
In my tmpl of a com_content view (first lines)
components\com_content\views\article\tmpl\default.php
<?php
defined('_JEXEC') or die;
JHtml::addIncludePath(JPATH_COMPONENT . '/helpers');
if(!defined('DS')) { define('DS',DIRECTORY_SEPARATOR); }
require_once JPATH_ROOT.DS."components".DS."com_mycom".DS."helpers".DS."helper.php";
echo MycomHelper::dosomething("hello!!!");
And now, you can see the phrase "Helper say: hello!!!" in every article joomla

Related

Class and Call to a member function on a non-objec

this time i have a hard problem. I have:
[folder] (file)
Structure directory
[class]
- (class.page.php)
- (class.main.php)
[core]
- (core.test.php)
Now class.data.php
<?php
class DataTools {
public function clean($string) {
if (!empty($string)) {
$string = addslashes($string);
$string = mysql_real_escape_string($string);
$string = (string)$string;
$string = stripslashes($string);
$string = str_replace(" ", "", $string);
$string = str_replace("(", "", $string);
$string = str_replace("=", "", $string);
return $string;
} else {
echo "Error";
die();
}
}
Now class.page.php
<?php
class Page {
public function __construct {
include "class.data.php";
$data = New DataTools();
}
?>
Now core.test.php
<?php
require_once "../class/class.page.php";
$page = new Page;
$nome = $data->clean("exemple"); // line 13
?>
When i open class.test.php it display this:
Fatal error: Call to a member function clean() on a non-object in /membri/khchapterzero/core/core.test.php on line 13( this is not important becouse i reduced the page for the topic, but the line in the original page was that i posted, the other line was comments)
This seems ok, if all files are in one folder it works fine, i try and there was no error. check your structures and names.
I check on:
Test->
class.data.php
class.page.php
core.test.php
in include only filename.
So checka again your paths
$data is defined in the Page object, it is not available as a variable in the global scope. And because you are not storing it as a class member of the Page obejct, it is also lost when PageĀ“s constructor resolves.
To fix this:
First make $data a class member of the Page class, so that it is not discarded after the constructor is done
<?php
class Page {
public function __construct {
require_once "../include/class.data.php";
$this->data = New DataTools();
}
?>
Then, access this data variable inside the Page instead of trying to call $data directly:
$nome = $page->data->clean("exemple");

PHP Vars From Included Bootstrap Not Showing Up in View

I have created my own little PHP framework for fun, however, I am having trouble passing variables from bootstrap to the views....
if I put an echo,print_r,var_dump my target variable in the bootstrap, the output is displayed in the browser before the tag... yet the target var in bootstrap.php is not available in the view, it is coming up as "" even though at the top of the page it is being output correctly....
Somethings I noticed from similar questions:
- The target variable is not being over written
- The include target path is correct and the file exists
- The file is only being included one time (include_once is only fired once)
Any ideas are greatly appreciated, I am pulling my hair out over here lol...
Source Code
https://gist.github.com/jeffreyroberts/f330ad4a164adda221aa
If you just want to display your site name, I think you can use a constant like that :
define('SITE_NAME', "Jeff's Site");
And then display it in your index.tpl :
<?php echo SITE_NAME; ?>
Or, you can send your variables to the view by extending a little bit your JLR_Core_Views :
class JLR_Core_Views
{
private $data;
public function loadView($templatePath, $data = array())
{
$this->data = $data;
$templatePath = JLR_ROOT . '/webroot/' . $templateName . '.tpl';
if(file_exists($templatePath)) {
// Yes, I know about the vuln here, this is just an example;
ob_start();
include_once $templatePath;
return ob_get_clean();
}
}
function __get($name)
{
return (isset($this->data[$name]))
? $this->data[$name]
: null;
}
}
Then, you can call your template like that :
$view = new JLR_Core_Views();
$view->loadView("index", array("sitename" => "Jeff's Site"));
And here is your index.tpl :
<?php echo $this->siteName; ?>
Below is another example of what you can do.
First, you create this class in order to store all the variables you want :
<?php
class JLR_Repository {
private static $data = array();
public function set($name, $value) {
self::$data[$name] = $value;
}
public function get($name) {
return (isset(self::$data[$name]))
? self::$data[$name]
: null;
}
}
?>
Then, when you want to store something in it :
JLR_Repository::set("sitename", "Jeff's Site");
And in your index.tpl :
<?php echo JLR_Repository::get("sitename"); ?>
try using the 'global' keyword - http://php.net/manual/en/language.variables.scope.php

Send php variable to a class and run mysql query with Smarty

I would like to send a php variable to a class that runs a mysql query. It is a typical search via html form. I have to use Smarty.
How can I pass the variable "$minta" to the sql query and how to get the result array back to the php to display?
The Smarty tpl file is OK (lista_keres.tpl with the ingatlank variable).
Thank you in advance.
Tuwanbi
The php:
if (isset($_POST['keresoszo'])){
include_once "classes/ingatlan.class.php";
include_once "classes/main.class.php";
include_once "classes/felhasznalo.class.php";
$ingatlan = new Ingatlan();
$felhasznalo = new Felhasznalo();
$minta = $_POST['keresoszo'];
$kereses = new Main();
$kereses->getKeresIngatlan($minta);
$smarty->assign("kapcsolattartok", $ingatlan->getKapcsolattartok());
$smarty->assign("ingatlank", $main->getKeresIngatlan());
$smarty->assign("include_file", lista_keres);
echo $minta;
}
The class:
<?php
class Main{
private $keresoszo;
...
public function getKeresIngatlan($minta){
$this->keresoszo=$minta;
$ret = array();
$sql="SELECT id FROM table WHERE id LIKE '% ".$keresoszo." %'";
$ret = $this->db->GetArray($sql);
return $ret;
}
}
?>
Declaring private $keresoszo; it becomes the class object and can be accessible by
$this->keresoszo in you sql query you have assigned the value to this object but haven't used it
<?php
class Main{
private $keresoszo;
...
public function getKeresIngatlan($minta){
$this->keresoszo=$minta;
$ret = array();
$sql="SELECT id FROM table WHERE id LIKE '% ".$this->keresoszo." %'";
$ret = $this->db->GetArray($sql);
return $ret;
}
}
?>
Here is what how you can get back the results
$kereses = new Main();
$results_set=$kereses->getKeresIngatlan($minta);
var_dump($results_set);// for testing only
$smarty->assign("my_results_set", $results_set);

How do I use a controller within a controller?

I am using Kohana 3.2 and I am having problems calling the ouput of a controller in another controller.
What I want...
In some pages I have got a menu, and in others I don't. I want to use make use of the flexability of the HMVC request system. In the controller of a page I want to call another controller which is responsible for the creation of the menu.
What I have a the moment:
file menu.php:
<?php defined('SYSPATH') or die('No direct script access.');
class Controller_Menu extends Controller
{
private $_model = null;
public function __construct(Request $request, Response $response)
{
parent::__construct($request, $response);
$this->_model = Model::factory('menu');
}
public function action_getMenu()
{
$content = array();
$content['menuItems'] = $this->_model->getMenuItems();
// Render and output.
$this->request->response = View::factory('blocks/menu', $content);
//echo '<pre>'; print_r($this->request->response->render()); echo '</pre>'; die();
}
}
somepage.php
public function action_index()
{
$this->template->title = 'someTitle';;
$contentData['pageTitle'] = 'someTitle';
$contentData['contentData'] = 'someData';
#include the menu
$menuBlock = Request::factory('menu/getMenu')->execute();
$menuData = array('menu' => $menuBlock);
$this->template->menu = View::factory('pages/menu')->set('menu',$menuData);
$this->template->content = View::factory('pages/somePage', $contentData);
$view = $this->response->body($this->template);
$this->response->body($view);
}
If I uncomment the following line in menu.php, I see the menu rendered:
//echo '<pre>'; print_r($this->request->response->render()); echo '</pre>'; die();
So I guess that part is alright. The problem is in the following line in somepage.php:
$menuBlock = Request::factory('menu/getMenu')->execute();
This gives me back a response object. Whatever I do, I do not get the output in $this->template->menu.
$this->template->menu = View::factory('pages/menu')->set('menu',$menuData);
What must I do to have $this->template->menu contain the view, so I can use it correctly?
I hope this all makes sense. This is the way I would like to do it, but maybe I am completely on the wrong track.
I would do it this way:
class Controller_Menu extends Controller
{
public function action_build()
{
// Load the menu view.
$view = View::factory('navigation/menu');
// Return view as response-
$this->response->body($view->render());
}
}
In your controller get the menu as follows:
// Make request and get response body.
$menu = Request::factory('menu/build')->execute()->body();
// e.g. assign menu to template sidebar.
$this->template->sidebar = Request:.factory('menu/build')->execute()->body();
I would not use the __construct method in your controllers. Use before() instead, this is sufficient for most of the problems (for example auth):
public function before()
{
// Call aprent before, must be done here.
parent::before();
// e.g. heck whether user is logged in.
if ( !Auth::instance()->logged_in() )
{
//Redirect if not logged in or something like this.
}
}
I found the answer to my problem in less than an hour after asking.
I just forgot to put it here.
In somePage.php change :
$menuBlock = Request::factory('menu/getMenu')->execute();
$menuData = array('menu' => $menuBlock);
$this->template->menu = View::factory('pages/menu')->set('menu',$menuData);
To:
$this->template->menu = Request::factory('menu/getMenuBlock')->execute()->body();
And in menu.php change:
$this->request->response = View::factory('blocks/menu', $content);
To:
$request = View::factory('blocks/menu', $content);
$this->response->body($request);
I hope this will help someone else.

Simple template var replacement, but with a twist

So I'm setting up a system that has a lot of emails, and variable replacement within it, so I'm writing a class to manage some variable replacement for templates stored in the database.
Here's a brief example:
// template is stored in db, so that's how this would get loaded in
$template = "Hello, %customer_name%, thank you for contacting %website_name%";
// The array of replacements is built manually and passed to the class
// with actual values being called from db
$replacements = array('%customer_name%'=>'Bob', '%website_name%'=>'Acme');
$rendered = str_replace(array_keys($replacements), $replacements, $template);
Now, that works well and good for single var replacements, basic stuff. However, there are some places where there should be a for loop, and I'm lost how to implement it.
The idea is there'd be a template like this:
"hello, %customer_name%, thank you for
requesting information on {products}"
Where, {products} would be an array passed to the template, which the is looped over for products requested, with a format like:
Our product %product_name% has a cost
of %product_price%. Learn more at
%product_url%.
So an example rendered version of this would be:
"hello, bob, thank you for requesting
information on:
Our product WidgetA has a cost of $1.
Learn more at example/A
Our product WidgetB has a cost of $2.
Learn more at example/B
Our product WidgetC has a cost of $3.
Learn more at example/C.
What's the best way to accomplish this?
Well, I really dont see the point in a template engine that uses repalcements/regex
PHP Is already a template engine, when you write <?php echo $var?> its just like doing <{$var}> or {$var}
Think of it this way, PHP Already translates <?php echo '<b>hello</b>'?> into <b>hello</b> by its engine, so why make it do everything 2 times over.
The way i would implement a template engine is like so
Firstly create a template class
class Template
{
var $vars = array();
function __set($key,$val)
{
$this->vars[$key] = $val;
}
function __get($key)
{
return isset($this->vars[$key]) ? $this->vars[$key] : false;
}
function output($tpl = false)
{
if($tpl === false)
{
die('No template file selected in Template::output(...)');
}
if(!file_exists(($dir = 'templates/' . $tpl . '.php')))
{
die(sprintf('Tpl file does not exists (%s)',$dir));
}
new TemplateLoader($dir,$this->vars);
return true;
}
}
This is what you use in your login such as index.php, you will set data just like an stdClass just google it if your unsure. and when you run the output command it sends the data and tpl to the next class below.
And then create a standalone class to compile the tpl file within.
class TemplateLoader
{
private $vars = array();
private $_vars = array(); //hold vars set within the tpl file
function __construct($file,$variables)
{
$this->vars = $variables;
//Start the capture;
ob_start();
include $file;
$contents = ob_get_contents();
ob_end_clean(); //Clean it
//Return here if you wish
echo $contents;
}
function __get($key)
{
return isset($this->vars[$key]) ? $this->vars[$key] : (isset($this->_vars[$key]) ? $this->_vars[$key] : false) : false;
}
function __set($key,$val)
{
$this->_vars[$key] = $val;
return true;
}
function bold($key)
{
return '<strong>' . $this->$key . '</string>';
}
}
The reason we keep this seperate is so it has its own space to run in, you just load your tpl file as an include in your constructor so it only can be loaded once, then when the file is included it has access to all the data and methods within TemplateLoader.
Index.php
<?php
require_once 'includes/Template.php';
require_once 'includes/TemplateLoader.php';
$Template = new Template();
$Template->foo = 'somestring';
$Template->bar = array('some' => 'array');
$Template->zed = new stdClass(); // Showing Objects
$Template->output('index'); // loads templates/index.php
?>
Now here we dont really want to mix html with this page because by seperating the php and the view / templates you making sure all your php has completed because when you send html or use html it stops certain aspects of your script from running.
templates/index.php
header
<h1><?php $this->foo;?></h1>
<ul>
<?php foreach($this->bar as $this->_foo):?>
<li><?php echo $this->_foo; ?></li>
<?php endforeach; ?>
</ul>
<p>Testing Objects</p>
<?php $this->sidebar = $this->foo->show_sidebar ? $this->foo->show_sidebar : false;?>
<?php if($this->sidebar):?>
Showing my sidebar.
<?php endif;?>
footer
Now here we can see that were mixing html with php but this is ok because in ehre you should only use basic stuff such as Foreach,For etc. and Variables.
NOTE: IN the TemplateLoader Class you can add a function like..
function bold($key)
{
return '<strong>' . $this->$key . '</string>';
}
This will allow you to increase your actions in your templates so bold,italic,atuoloop,css_secure,stripslashs..
You still have all the normal tools such as stripslashes/htmlentites etc.
Heres a small example of the bold.
$this->bold('foo'); //Returns <strong>somestring</string>
You can add lots of tools into the TempalteLoader class such as inc() to load other tpl files, you can develop a helper system so you can go $this->helpers->jquery->googleSource
If you have any more questions feel free to ask me.
----------
An example of storing in your database.
<?php
if(false != ($data = mysql_query('SELECT * FROM tpl_catch where item_name = \'index\' AND item_save_time > '.time() - 3600 .' LIMIT 1 ORDER BY item_save_time DESC')))
{
if(myslq_num_rows($data) > 0)
{
$row = mysql_fetch_assc($data);
die($row[0]['item_content']);
}else
{
//Compile it with the sample code in first section (index.php)
//Followed by inserting it into the database
then print out the content.
}
}
?>
If you wish to store your tpl files including PHP then that's not a problem, within Template where you passing in the tpl file name just search db instead of the filesystem
$products = array('...');
function parse_products($matches)
{
global $products;
$str = '';
foreach($products as $product) {
$str .= str_replace('%product_name%', $product, $matches[1]); // $matches[1] is whatever is between {products} and {/products}
}
return $str;
}
$str = preg_replace_callback('#\{products}(.*)\{/products}#s', 'parse_products', $str);
The idea is to find string between {products} and {products}, pass it to some function, do whatever you need to do with it, iterating over $products array.
Whatever the function returns replaces whole "{products}[anything here]{/products}".
The input string would look like that:
Requested products: {products}%product_name%{/products}

Categories