I know PHPUnit tests can be executed from the command line, but is there an easy way to run it from the browser. For example, I have:
class testsSuite extends PHPUnit_Framework_TestSuite
{
public function __construct ()
{
$this->setName('testsSuite');
$this->addTestSuite('MyFirstTest');
}
public static function suite ()
{
return new self();
}
}
And then I have:
class MyFirstTest extends PHPUnit_Framework_TestCase
{
protected function setUp ()
{
parent::setUp();
}
protected function tearDown ()
{
parent::tearDown();
}
public function __construct ()
{
}
public function test__construct ()
{
}
public function test__destruct () {
}
public function testCalculateCost ()
{
print 1; die();
}
}
Is there a URL I can enter in my browser to execute this test? Something like:
http://localhost/tests/testsSuite/calculateCost
Or something similar
There is VisualPHPUnit.
At work we sometimes run from browser, using in its basic form a php-script containing:
$argv = array(
'--configuration', 'phpunit.xml',
'./unit',
);
$_SERVER['argv'] = $argv;
PHPUnit_TextUI_Command::main(false);
So you basically put all parameters you normally type on the commandline in an array, and set it in the $_SERVER-global. PHPUnit_TextUI_Cmmand::main(false); then runs your tests. The false-parameter makes sure no exit() is called.
In the PHPUnit.xml I configure to log to a JSON file, and the php-script reads that file to show the results (which it can do after the tests because no exit was called).
Note: this is very barebone, simplistic and crude.
I have found a solution that works well:
<?php
define("PHPUNIT_COMPOSER_INSTALL","vendor/autoload.php");
require PHPUNIT_COMPOSER_INSTALL;
$query = $_SERVER["QUERY_STRING"];
//$_SERVER["QUERY_STRING"] to $_SERVER['argv'];
$_SERVER['argv'] = explode("&",$query);
//PHPUnit use $_SERVER['argv'] for input value
PHPUnit\TextUI\Command::main(false);
/*Use
command line "./vendor/bin/phpunit param1 param2 param..."
browser URI "localhost?param1¶m2¶m..."
*/
Related
How can I instance an Magento\Customer\Model\AccountManagement inside a Command in a custom module?
I'm trying to create a command to reset all customers passwords
You can probably just use DI for the AccountManagementInterface, like this snippet taken from Magento's code:
class Command
{
public function __construct(
AccountManagementInterface $customerAccountManagement
) {
$this->customerAccountManagement = $customerAccountManagement;
}
public function whatever() {
$this->customerAccountManagement->initiatePasswordReset(
$email,
AccountManagement::EMAIL_RESET
);
}
}
How can I implement mysqli in an extended class?
I am uploading an image and storing it in a MySQL database, but I get this error:
Notice: Undefined variable: mysqli in ...ecc/ecc/ on line 33
Fatal error: Call to a member function query() on a non-object in ...ecc/ecc/ on line 33
Here is my test code:
<?php
interface ICheckImage {
public function checkImage();
public function sendImage();
}
abstract class ACheckImage implements ICheckImage {
public $image;
private $mysqli;
public function _construct(){
$this->image = $_POST['image'];
$this->mysqli = new mysqli('localhost','test','test','test');
}
}
class Check extends ACheckImage {
public function checkImage() {
if($this->image > 102400) {
echo "File troppo grande";
}
}
public function sendImage() {
//This is the line 33 give me the error
if ($mysqli->query("INSERT INTO images (image) VALUES ('$this->image')")) {
echo "Upload avvenuto  ";
} else {
echo "Errore  " . $mysqli->error;
}
}
}
$form = new Check();
$form->checkImage();
$form->sendImage();
?>
There are some errors in your code.
The $mysqli member is private inside the abstract class. It will not be inherited by the Check class, so it does not exist there. Make it protected.
Access to the members of a class always needs $this-> in front, specifically $this->mysqli in this instance.
The constructor function must be named __construct with two underscores in front.
The image check looks wrong. $_POST['image'] does contain something that you expect to store in the database, but you also compare it with an integer value and seem to echo an error message if it is bigger. While the data handling will work, e.g. you can compare a string from POST data with an integer, it looks like you want something else.
I am trying to create a helper of my own. The Safecheck folder is located in the library folder and contains a Helper folder. The class is called Safecheck_Helper_Authority.php (inside library/Safecheck/Helper).
In Bootstrap.php:
protected function _initHelper()
{
Zend_Controller_Action_HelperBroker::addPrefix('Safecheck_Helper');
}
In Safecheck_Helper_Authority.php:
class Safecheck_Helper_Authority extends Zend_Controller_Action_Helper_Abstract
{
public function hasAuthority($userId, array $ids)
{
}
}
I want to user the functions inside this class. But I get the error "Message: Action Helper by name Authority not found", triggered by the following code:
$this->_helper->authority('hasAuthority');
Maybe I am not calling it with the right code? Am I missing something?
in order to call an action helper in this manner $this->_helper->authority('hasAuthority'); you need to define the direct() method in your helper.
class Safecheck_Helper_Authority extends Zend_Controller_Action_Helper_Abstract
{
public function direct($userId, array $ids)
{
// do helper stuff here
}
}
an easy way to register the helper path and prefix is to use the application.ini:
resources.frontController.actionhelperpaths.Safecheck_Helper = APPLICATION_PATH "/../library/Safecheck/Helper"
to do it in bootstrap (not sure if addPrefix() works with library namespaces):
protected function _initHelper()
{
//addPath(path_to_helper, helper_prefix)
Zend_Controller_Action_HelperBroker::addPath('/../library/Safecheck/Helper', 'Safecheck_Helper');
}
a Simple example of an action helper:
class Controller_Action_Helper_Login extends Zend_Controller_Action_Helper_Abstract
{
//prepares a login form for display
public function direct()
{
$form = new Application_Form_Login();
$form->setAction('/index/login');
return $form;
}
}
Have in your application.ini something similar to
resources.frontController.actionhelperpaths.Application_Action_Helper = APPLICATION_PATH "/../classes/Application/Action/Helper"
The path should be changed to reflect your file path.
I'm trying to make a way to disable some view helpers that are inside "application/views/helpers"...
What I really want is to put some options on the application.ini to enable or disable some Helpers.
Example on application.ini:
helpers.Helper1=on
helpers.Helper2=off
Now the problem is that when a Helper is off, I want to rewrite some functions of this helper in order to return a different result on the view. In this way, I don't need to change anything in the view script.
I thought in having 2 different php files for each helper, in different locations. One with the real helper and another with the changed helper (to work when it is off on the application.ini).
The problem is that I don't know how to tell the view which one it shoul load...
Does anyone know how it could be done?
FINAL CODE
Ok, after many tries, I put it to work with the following code:
Bootstrap
protected function _initConfigureHelpers(){
$this->bootstrap('view');
$view = $this->getResource('view');
$view->addHelperPath("./../library/ConfigHelpers","Configurable_Helper");
$viewRenderer = Zend_Controller_Action_HelperBroker::getStaticHelper(
'ViewRenderer'
);
$viewRenderer->setView($view);
$front = Zend_Controller_Front::getInstance();
$front->registerPlugin(new Application_Plugin_ViewPlugins());
return $view;
}
Application_Plugin_ViewPlugins
class Application_Plugin_ViewPlugins extends Zend_Controller_Plugin_Abstract
{
public function preDispatch(Zend_Controller_Request_Abstract $request){
$front=Zend_Controller_Front::getInstance();
$bootstrap=$front->getParam('bootstrap');
$options=$bootstrap->getOption("helpers");
if (is_array($options)){
$view = $bootstrap->getResource('view');
foreach($options as $option => $value){
$helper=$view->getHelper($option);
if ($helper){
if ($value=="off")
$helper->__disable();
else if ($value!="on")
throw new Exception('The value of helpers.'.$option.' must be "on" or "off" on application.ini.');
} else {
throw new Exception("Inexistent Helper");
}
}
}
}
}
Modified helper example
require_once APPLICATION_HELPERS."CssCrush.php";
class Configurable_Helper_CssCrush extends Zend_View_Helper_CssCrush {
protected $__config_enabled = true;
public function __disable(){
$this->__config_enabled = false;
return $this;
}
public function __enable(){
$this->__config_enabled = true;
return $this;
}
public function cssCrush(){
if ($this->__config_enabled){
return parent::cssCrush();
} else{
return new Modified_CssCrush();
}
}
}
class Modified_CssCrush {
public static function file ( $file, $options = null ) {
return $file;
}
}
APPLICATION_HELPERS is defined on /public/index.php as "../application/views/helpers/".
Now, when I want to add a configurable helper, I put the original helper on "/application/views/helpers/" and then, create a modified version of it on "/library/ConfigHelpers" with the structure of the example above.
What I think you want is Dependency Injection which is coming in zf2, but not available in zf1.
With some tinkering though you can get what you need.
Configuring helpers in the bootstrap
(assumes default project structure)
View helpers paths config : application/configs/application.ini:
resources.view.helperPath.Zf_View_Helper_ = "Zf/View/Helper"
A simple configurable helper, (allows disable/enable but you can obviously add any methods you need (use this as base class for helpers that need the behaviour)
class Zf_View_Helper_Configurable extends Zend_View_Helper_Abstract
{
protected $isEnabled = true;
public function configurable()
{
return $this;
}
public function disable()
{
$this->isEnabled = false;
return $this;
}
public function enable()
{
$this->isEnabled = true;
return $this;
}
public function __toString()
{
if ($this->isEnabled) {
return 'Configurable is enabled';
} else {
return 'Configurable is disabled';
}
}
}
And configure the helpers in the bootstrap:
public function _initConfigureHelpers()
{
$this->bootstrap('view');
$view = $this->getResource('view');
$configurableHelper = $view->configurable();
$configurableHelper->disable();
}
You can add options in the .ini file and grab them in the bootstrap initConfigureHelpers() method.
If you want this behaviour from any default zf helper, do what #Ratzo said and extend those helpers and add the required behaviour and then configure them in your bootstrap.
Please take a look at the following link Zend_View link
Below is an important points you should consider from the Zend docs.
Note: Default Helper Path
The default helper path always points to the Zend Framework view
helpers, i.e., 'Zend/View/Helper/'. Even if you call setHelperPath()
to overwrite the existing paths, this path will be set to ensure the
default helpers work.
This means that you can't really turn off the helpers, unless you want to go about extending the Zend_View object and overwrite the setHelperPath method. This is not the way to go though.
Here is probably what you want to do. First though, here is my assumption.
Assumption : You want to write your own view helper that slightly alters what the current view helpers do by changing a few methods here or there.
Here is what you should do to accomplish that.
First, write your view helper. Make sure the last part of the class name is the same as the view helper you want to 'overwrite'. You don't have to, but this makes sure the original helper can't be used anymore.
class My_View_Helper_BaseUrl extends Zend_View_Helper_BaseUrl
{
private $_enabled = true;
public function setEnabled( $bool ){ $this->_enabled = (boolean) $bool; }
public function baseUrl(){
if( $this->_enabled ){
return 'testUrl'; //other code
}
else return parent::baseUrl();
}
Now that you have that, do the following
$view->setHelperPath('/path/to/my/helpers', 'My_View_Helper'); //1
echo $view->baseUrl(); //2
Excellent. Now you've effectively shadowed the original BaseUrl helper.
The above code will make it so that the view scans your directory
for any helpers before scanning the default zend directory. When it gets to line
2 the view will find YOUR baseUrl helper first and use THAT instead of the
original baseUrl helper. In the above example it should echo
'testurl' instead of the normal baseUrl behavior.
You can make a custom helper that extends the original helper, for example
class My_Helper_Url extends Zend_View_Helper_Url
{}
and rewrite the methods as you need.
Iam writing an application using Zend Framework 1.10.2.
I created few model classes and a controller to process them.
When Iam executing my application and accessing the admin controller. Iam seeing this error.
Fatal error: Class 'Application_Model_DbTable_Users' not found in C:\xampp\htdocs\bidpopo\application\controllers\AdminController.php on line 16
The error clearly shows its an autoloading error.
Hence I wrote this code in the bootstrap file.
protected function initAutoload()
{
$modeLoader = new Zend_Application_Module_AutoLoader(array
('namespace'=>'','basePath'=>APPLICATION_PATH ));
//echo(APPLICATION_PATH);
return $modeLoader;
}
Still the error remains :( . Can anyone suggest me what Iam missing out here?
This is the location of the Model Users class.
C:\xampp\htdocs\bidpopo\application\models\DbTable\Users.php
This is its code.
class Application_Model_DbTable_Users extends Zend_Db_Table_Abstract
{
//put your code here
protected $_name='users';
public function getUser($id)
{
$id = (int)$id;
$row = $this->fetchrow('id='.$id);
if(!$row)
{throw new Exception("Could not find row id - $id");}
return $row->toArray();
}
public function addUser($userDetailArray)
{
$this->insert($userDetailsArray);
}
public function updateUser($id,$userDetailArray)
{
$this->update($userDetailArray,'id='.(int)$id);
}
public function deleteUser($id)
{
$this->delete('id='. (int)$id);
}
}
This is the Admin Controller's code
class AdminController extends Zend_Controller_Action
{
public function init()
{
/* Initialize action controller here */
}
public function indexAction()
{
$this->view->title= "All Users";
$this->view->headTitle($this->view->title);
$users = new Application_Model_DbTable_Users();
$this->view->users = $users->fetchAll();
}
public function addUserAction()
{
// action body
}
public function editUserAction()
{
// action body
}
public function deleteUserAction()
{
// action body
}
You application classes don't follow the proper naming convention for the namespace you've set. The Zend_Application_Module_AutoLoader is a little different than the normal autoloader in that it doesn't simply change the '_' in the class name with '/'. It looks at the second part of the class name and then checks a folder for the existence of the class based on that.
You need to change the line:
$modeLoader = new Zend_Application_Module_AutoLoader(array(
'namespace'=>'Application',
'basePath'=>APPLICATION_PATH
));
This means it will autoload all module classes prefixed with 'Application_'. When it the second part of the class is 'Model_' it will look in "{$basePath}/models" for the class. The '_' in the rest of the class name will be replaced with '/'. So the file path of the file will be "{$basePath}/models/DbTable/Users.php".
Read more here.