ZF2 get template name - templates

Is it possible to retrieve the template name inside of a template (the .phtml thingy)? I can get the ViewModel's template with
echo $this->viewModel()->getCurrent()->getTemplate();
but that doesn't work on partials (obviously). So how can I retrieve the template's name currently being rendered?

You could do this like this:
class Module
{
public function onBootstrap (MvcEvent $e)
{
$eventManager = $e->getApplication ()
->getEventManager ();
$eventManager->attach (
MvcEvent::EVENT_RENDER,
function (MvcEvent $e)
{
$layout = $e->getViewModel ();
$view = reset ($layout->getChildren ());
$view->template1 = $view->getTemplate ();
});
}
and then in the view:
<?php
echo $this->template1;
?>

Simple, but highly effective, solution:
$where_am_i = __FILE__;

Related

Multiple regex inside controller instead of mutliple routes with single regex

I run Laravel 5.4.
I have those routes :
<?php
Route::get('/users/{name}', 'UsersController#showByText')->where('name', '[\w]+');
Route::get('/users/{id}', 'UsersController#showById')->where('id', '[\d]+');
?>
And my controllers :
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class DashboardController extends Controller
{
function showByText($name)
{
return DB::table('users')->where('name', 'LIKE', $name)->get();
}
function showById($id)
{
return DB::table('users')->where('id', $id)->get();
}
}
?>
Question :
Could I end up with one single method, to be able to do :
<?php
Route::get('/users/{mixed}', 'UsersController#show');
?>
And my controller would look like :
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class DashboardController extends Controller
{
function show()
{
if( Request::match('mixed', '[\w]+') )
{
return DB::table('users')->where('name', 'LIKE', $mixed)->get();
}
else if( Request::match('mixed', '[\d]+') )
{
return DB::table('users')->where('id', $mixed)->get();
}
}
}
?>
I know Request::match() does not exists, and knowing that Route::pattern('id', '[\d]+'); will force my method show to be compliant only for digits. I would like to know if there is a shorthand for preg_match() with the Request component.

how to post form and get data from database in opencart

how to post form and get posted data to controller and i don't know how to pass posted variable from controller to model after getting i want to pass variables to views
controller.php
if(isset($_POST["email"]))
{
$email=$_POST["email"];
}
$this->load->model('order/myorder');
$data['data1']=$this->model_order_myorder->getOrder($email) ;
view.php
foreach ($data1 as $row)
{
echo echo $row->order_id;
}
model.php
<?php
class ModelOrderMyorder extends Model {
public function getOrder($email) {
$sql = "SELECT * FROM ".DB_PREFIX."order,".DB_PREFIX."order_product WHERE ".DB_PREFIX."order.email='$email'";
$query = $this->db->query($sql);
return $query ;
}
}
Regards
Dev
You simply pass the value as the parameter, e.g.
$this->model_shipping_order->getordertracking($_POST['email']) {
You should also escape the parameter in your query to prevent SQL injection e.g.
WHERE email = '" . $this->db->escape($email) . "' ");

Can't get my custom template to work with my custom subclass

I'm developing a subclass of DropdownField and I'm trying to couple it with a corresponding DrodownFieldData.ss template without a success.
I flushed the cache repeatedly.
I deleted the cache folder on my localhost (XAMPP)
I moved the template around to various locations of my 'simple' theme: /simple/templates, /simple/templates/forms, /simple/templates/Includes
As you can see, the template name does not have an underscore character which has been reported to cause problems
I'm calling it as in:
return $this->customise($properties)->renderWith('DropdownFieldData');
Do you have any other ideas that I could give a try?
This is the code. It's basically a copy of DropdownField, skimmed down to the Field method.
<?php
class DropdownFieldData extends DropdownField {
public function Field($properties = array()) {
$source = $this->getSource();
$options = array();
if($source) {
// SQLMap needs this to add an empty value to the options
if(is_object($source) && $this->emptyString) {
$options[] = new ArrayData(array(
'Value' => '',
'Title' => $this->emptyString,
));
}
foreach($source as $value => $title) {
$selected = false;
if($value === '' && ($this->value === '' || $this->value === null)) {
$selected = true;
} else {
// check against value, fallback to a type check comparison when !value
if($value) {
$selected = ($value == $this->value);
} else {
$selected = ($value === $this->value) || (((string) $value) === ((string) $this->value));
}
$this->isSelected = $selected;
}
$disabled = false;
if(in_array($value, $this->disabledItems) && $title != $this->emptyString ){
$disabled = 'disabled';
}
$options[] = new ArrayData(array(
'Title' => $title,
'Value' => $value,
'Selected' => $selected,
'Disabled' => $disabled,
));
}
}
$properties = array_merge($properties, array('Options' => new ArrayList($options)));
return $this->customise($properties)->renderWith('DropdownFieldData');
// return parent::Field($properties);
}
}
I had a similar problem that was the result of timing (there was a template loaded later that replaced my own customisation, but only when using the default form template). The fix was making sure the subclassed form field had its own version of the FormField Holder method. EG:
public function FieldHolder($properties = array()) {
$obj = $properties ? $this->customise($properties) : $this;
return $obj->renderWith($this->getTemplates());
}
The template should be in templates/forms/CustomField.ss. I don't think it should matter if this is in your theme folder, in mysite, or in a module folder.
You could try the following:
rename your template DropdownFieldData_holder.ss
move DropdownFieldData_holder.ss into mysite/templates/DropdownFieldData_holder.ss
use the setFieldHolderTemplate method on your field, ie $this->setFieldHolderTemplate('DropdownFieldData_holder');
You'll also find that the fields are rendered using two templates, one of them being suffixed with '_holder', which acts as a wrapper, while the other one renders the field itself, so depending on how you want to customise your field, you might have to create both.
Have a look at the FormField class to get a better understanding on how fields are rendered, as they use a slightly different mechanism than page types
The key was to keep the template in [yourmodule]/templates, rather than in any theme's location.

Unit testing helpers in CakePHP

I created a new helper called AdvHtmlHelper.
class AdvHtmlHelper extends AppHelper {
var $helpers = array('Form');
function textbox($fieldName, $options = array()) {
$output = $this->Form->input($fieldName, array('before' => '<div class="outerdiv"><div class="leftfields"><div class="txt1">', 'between' => '</div><div class="colon"> : </div></div><div class="rightfields"><div class="input">'));
$output .= '</div></div></div><div class="space"></div>';
return $output;
}
}
And I created a test for it
App::import('Helper', 'AdvHtml');
App::import('Helper', 'Form');
App::import('Helper', 'Html');
App::import('Core', 'View');
class AdvHtmlTest extends CakeTestCase {
private $advHtml = null;
//Here we instantiate our helper, and all other helpers we need.
public function startTest() {
$this->advHtml = new AdvHtmlHelper();
$this->advHtml->Form = new FormHelper();
$this->advHtml->Form->Html = new HtmlHelper();
$this->view = new View($this->Controller);
}
//testing textbox() function.
public function testTextbox() {
$result = '<div class="input text"><div class="outerdiv"><div class="leftfields"><div class="txt1"><label for="new">New</label></div><div class="colon"> : </div></div><div class="rightfields"><div class="input"><input name="data[new]" type="text" id="new" /></div></div></div></div><div class="space"></div>';
$this->assertEqual($result, $this->advHtml->textbox('new'));
}
}
I get the following error when I try to run the test. Line 10 of the helper code is the call to the form helper.
Fatal error: Call to a member function input() on a non-object in /opt/lampp/htdocs/mali/app/views/helpers/adv_html.php
How do I test a helper which calls another helper?
on line 10
EDIT: Answered. Updated with my final test case for reference.
You have to set the form helper as a property of the advHtml helper when setting up the helpers:
public function startTest() {
$this->advHtml = new AdvHtmlHelper();
$this->advHtml->Form = new FormHelper();
}

Zend Framework: How to unit test a model using Zend_Service_Twitter

I have been getting into Unit Testing with Zend Framework. I am getting used to the other things it provide but I am having a hard time understanding Mock Objects.
For this example, I am trying to use a Mock Object to test out my model.
<?php
class Twitter_Model_Twitter
{
private $_twitter;
/**
* Make the options injectable.
* __contruct($auth, $key)
*/
public function __construct()
{
$config = new Zend_Config_Ini(APPLICATION_INI, APPLICATION_ENV);
$key = $config->encryption->salt;
$iv_size = mcrypt_get_iv_size(MCRYPT_XTEA, MCRYPT_MODE_ECB);
$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
$password = mcrypt_decrypt(MCRYPT_XTEA, $key, $password, MCRYPT_MODE_ECB, $iv);
$this->_twitter = new Zend_Service_Twitter($username, $password);
}
public function verifyCredentials()
{
return $this->_twitter->account->verifyCredentials();
}
public function friendsTimeline($params)
{
return $this->_twitter->status->friendsTimeline($params);
}
}
For my unit test:
require_once ('../application/models/Twitter.php');
class Model_TwitterTest extends ControllerTestCase
{
/**
* #var Model_Twitter
*/
protected $_twitter;
public function testfriendsTimeline()
{
$mockPosts = array('foo', 'bar');
//my understanding below is:
//get a mock of Zend_Service_Twitter with the friendsTimeline method
$twitterMock = $this->getMock('Zend_Service_Twitter', array('friendsTimeline'));
/*
line above will spit out an error:
1) testfriendsTimeline(Model_TwitterTest)
Missing argument 1 for Mock_Zend_Service_Twitter_9fe2aeaa::__construct(), called in
/Applications/MAMP/bin/php5/lib/php/PHPUnit/Framework/TestCase.php on line 672 and
defined /htdocs/twitter/tests/application/models/TwitterTest.php:38
*/
$twitterMock->expects($this->once())
->method('friendsTimeline')
->will($this->returnValue($mockPosts));
$model = new Twitter_Model_Twitter();
$model->setOption('twitter', $twitterMock);
$posts = $model->friendsTimeline(array('count'=>20));
$this->assertEquals($posts, $mockPosts);
}
}
How would you test the following?
1) verifyCredentials()
2) friendsTimeline()
Thanks,
Wenbert
I am going to answer this question. I think I have made this work thanks to zomg from #zftalk.
Here is my new Twitter Model:
<?php
//application/models/Twitter.php
class Twitter_Model_Twitter
{
private $_twitter;
private $_username;
private $_password;
public function __construct(array $options = null)
{
if (is_array($options)) {
$this->setOptions($options);
$this->_twitter = new Zend_Service_Twitter($this->_username, $this->_password);
} else {
$twitterAuth = new Zend_Session_Namespace('Twitter_Auth');
$config = new Zend_Config_Ini(APPLICATION_INI, APPLICATION_ENV);
$key = $config->encryption->salt;
$iv_size = mcrypt_get_iv_size(MCRYPT_XTEA, MCRYPT_MODE_ECB);
$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
$password = mcrypt_decrypt(MCRYPT_XTEA, $key, $twitterAuth->password, MCRYPT_MODE_ECB, $iv);
$username = $twitterAuth->username;
$this->_twitter = new Zend_Service_Twitter($username, $password);
}
}
public function setOptions(array $options)
{
$methods = get_class_methods($this);
foreach ($options as $key => $value) {
$pieces = explode('_', $key);
foreach($pieces AS $piece_key => $piece_value) {
$pieces[$piece_key] = ucfirst($piece_value);
}
$name = implode('',$pieces);
$method = 'set' . $name;
//$method = 'set' . ucfirst($key);
if (in_array($method, $methods)) {
$this->$method($value);
}
}
return $this;
}
//I added this method. So that I could "inject"/set the $_twitter obj
public function setTwitter($obj)
{
$this->_twitter = $obj;
return $this;
}
public function verifyCredentials()
{
return $this->_twitter->account->verifyCredentials();
}
public function friendsTimeline($params)
{
return $this->_twitter->status->friendsTimeline($params);
}
//in the real code, more will go here...
}
And in my Unit Test, I have this:
<?php
// tests/application/models/TwitterTest.php
require_once ('../application/models/Twitter.php');
class Model_TwitterTest extends ControllerTestCase
{
public function testVerifyCredentials()
{
$stub = $this->getMock('Zend_Service_Twitter', array('verifyCredentials'),array(),'',FALSE);
//FALSE is actually the 5th parameter to flag getMock not to call the main class. See Docs for this.
//Now that I have set the $_twitter variable to use the mock, it will not call the main class - Zend_Rest_Client (i think)
$stub->expects($this->once())
->method('verifyCredentials');
$model = new Twitter_Model_Twitter();
//this is the part where i set the $_twitter variable in my model to use the $stub
$model->setOptions(array('twitter'=>$stub));
$model->verifyCredentials();
}
}
Anyways, I think I got it working.
1) The unit test no longer tried to connect to twitter.com:80
2) After I got the setOptions() working in the Twitter_Model, $model->verifyCredentials() in my unit test was successfully called.
I will wait for others in Stackoverflow to confirm that is the right answer. For the meantime, would like to hear from you guys.
Thanks!!!