I try to launch the functions of a joomla controller from an external script. The beginning of the script works very well but the use of the controller does not.
Thank you for your help,
<?php
define('_JEXEC', 1);
// this file is in a subfolder 'cron' under the main joomla folder
define('JPATH_BASE', realpath(dirname(__FILE__) . '/..'));
require_once JPATH_BASE . '/includes/defines.php';
require_once JPATH_BASE . '/includes/framework.php';
use Joomla\CMS\Factory;
// instantiate application
$app = Factory::getApplication('site');
// database connection
$db = Factory::getDbo();
jimport('joomla.application.component.controller');
JLoader::import('Article', JPATH_ROOT . '/components/com_content/controllers');
$controller = JControllerLegacy::getInstance('Article');
var_dump($controller);
I don't get anything to instantiate a controller from any other place instead of the controller's component.
So I visit the BaseController class where the getInstance() method lays. You can hack this by setting a task through application input.
<?php
define('_JEXEC', 1);
// This file is in a subfolder 'cron' under the main joomla folder
define('JPATH_BASE', realpath(dirname(__FILE__) . '/..'));
require_once JPATH_BASE . '/includes/defines.php';
require_once JPATH_BASE . '/includes/framework.php';
use Joomla\CMS\Factory;
// Instantiate application
$app = Factory::getApplication('site');
// Get the input instance
$input = $app->input;
// Database connection
$db = Factory::getDbo();
/**
* You have to provide a task for getting the controller instance.
* The `article` is the controller filename as well as the controller class's suffix
* See the controller class name is `ContentControllerArticle`
*
*/
$input->set('task', 'article.');
/**
* The first argument of the getInstance() function is the type.
* The type is the component name here.
* And you have to pass the base_path of the component through the $config argument.
*/
$controller = JControllerLegacy::getInstance('Content', ['base_path' => JPATH_ROOT . '/components/com_content']);
echo "<pre>";
print_r($controller);
echo "</pre>";
Related
I want to add Middleware to my Slim project that checks the ip of the user before allowing them access.
My middleware class:
<?php
namespace App\Middleware;
Class IpFilter
{
protected $request_ip;
protected $allowed_ip;
public function __construct($allowedip = array('127.0.0.1'))
{
$this->request_ip = app()->request()->getIp();
$this->allowed_ip = $allowedip;
}
public function call()
{
$checkit = checkIp();
$this->next->call();
}
protected function checkIp()
{
if (!in_array($this->request_ip, $this->allowed_ip))
$app->halt(403);
}
}
My Bootstrap index.php:
<?php
// To help the built-in PHP dev server, check if the request was actually for
// something which should probably be served as a static file
if (PHP_SAPI === 'cli-server' && $_SERVER['SCRIPT_FILENAME'] !== __FILE__) {
return false;
}
require __DIR__ . '/../vendor/autoload.php';
require '../app/middleware/ipfilter.php';
// Instantiate the app
$settings = require __DIR__ . '/../app/settings.php';
$app = new \Slim\App($settings);
$app->get('/test', function() {
echo "You look like you're from around here";
});
// Set up dependencies
require __DIR__ . '/../app/dependencies.php';
// Register middleware
require __DIR__ . '/../app/middleware.php';
// Register routes
require __DIR__ . '/../app/routes.php';
$app->add(new IpFilter);
// Run
$app->run();
I am using a slim skeleton project for my project setup. I get the following error when I run this code.
Fatal error: Class 'IpFilter' not found in
/Applications/XAMPP/xamppfiles/htdocs/slimtest/my-app/public/index.php
on line 34
I still don't properly understand how to add custom classes for middleware in slim. I've seen several tutorials that just make the class and use $app->add('new class) to add the middleware but I can't figure it out. Is there a file I need to update and I am just missing it?
It's been a long weekend with slim and not a lot of resources out there so any help would be greatly appreciated.
UPDATE:
When I remove the namespace App\Middleware from ipfilter.php I don't get the same error. This time I get
Fatal error: Call to undefined method IpFilter::request() in /Applications/XAMPP/xamppfiles/htdocs/slimtest/my-app/app/middleware/ipfilter.php on line 15
Which I understand why but I thought it might help troubleshoot and get to the root of the problem.
Okay, Finally got it to work.
Index.php
<?php
// To help the built-in PHP dev server, check if the request was actually for
// something which should probably be served as a static file
if (PHP_SAPI === 'cli-server' && $_SERVER['SCRIPT_FILENAME'] !== __FILE__) {
return false;
}
use App\Middleware\IpFilter;
require __DIR__ . '/../vendor/autoload.php';
require __DIR__ . '/../app/middleware/ipfilter.php';
// Instantiate the app
$settings = require __DIR__ . '/../app/settings.php';
$app = new \Slim\App($settings);
$app->get('/test', function() {
echo "You look like you're from around here";
});
// Set up dependencies
require __DIR__ . '/../app/dependencies.php';
// Register middleware
require __DIR__ . '/../app/middleware.php';
// Register routes
require __DIR__ . '/../app/routes.php';
$app->add(new IpFilter);
// Run
$app->run();
ipfilter.php
<?php
namespace App\Middleware;
Class IpFilter
{
private $whitelist = arrray('127.0.0.1')
protected $request_ip;
public function __invoke($request, $response, $next)
{
$request_ip = $request->getAttribute('ip_address');
return $next($request, $response);
}
public function call()
{
$checkit = checkIp();
$this->next->call();
}
protected function checkIp()
{
if (!in_array($this->request_ip, $this->whitelist)
$app->halt(403);
}
}
KEY: Using App\Middleware\Ipfilter in the index.php. I though using require to add the class would be enough but apparently no.
Shout out to codecourse.com, really helped.
I'm trying to instantiate a controller and execute some methods but no result :(
jimport('joomla.application.component.controller');
$controller = JController::getInstance('com_shop');
$controller->my_method($arg1, $arg2);
Any idea?
This won't work try: JControllerLegacy::getInstance('CONTROLLERNAME') assuming that the controller you are calling follows the naming convention
<COMPONENTNAME><Controller><CONTROLLERNAME> for example WeblinksControllerWeblink
following is controller instantiation code taken form lender. And you don't need to use jimport in Joomla 3 extensions. Joomla auto load all classes starting with J prefix.
<?php // No direct access
defined( '_JEXEC' ) or die( 'Restricted access' );
//sessions
jimport( 'joomla.session.session' );
//load tables
JTable::addIncludePath(JPATH_COMPONENT.'/tables');
//load classes
JLoader::registerPrefix('Lendr', JPATH_COMPONENT);
//Load plugins
JPluginHelper::importPlugin('lendr');
//application
$app = JFactory::getApplication();
// Require specific controller if requested
if($controller = $app->input->get('controller','default')) {
require_once (JPATH_COMPONENT.'/controllers/'.$controller.'.php');
}
// Create the controller
$classname = 'LendrController'.$controller;
$controller = new $classname();
// Perform the Request task
$controller->execute();
I am trying to make a login system for an android application that works in with my 2.5 Joomla website. I am trying to do this by making a Joomla plugin which the android application sends post data to a php file which that then authenticates the user to see if the credentials are correct or not for the login. I have been trying to get this working all afternoon but it seems all my attempts of importing JFactory are failing.
I have the below code which bugs out at the first mention of JFactory. My attempt of importing it is not working either.
<?php
//needed to be commented out otherwise the android application cannot send data to the file
//defined('_JEXEC') or die;
define('_JREQUEST_NO_CLEAN', 1);
define('_JEXEC', 1);
define('DS', DIRECTORY_SEPARATOR);
if (file_exists(dirname(__FILE__) . '/defines.php')) {
include_once dirname(__FILE__) . '/defines.php';
}
if (!defined('_JDEFINES')) {
define('JPATH_BASE', dirname(__FILE__));
require_once JPATH_BASE.'/includes/defines.php';
}
require_once JPATH_BASE.'/includes/framework.php';
require_once JPATH_BASE.'/includes/helper.php';
require_once JPATH_BASE.'/includes/toolbar.php';
require JPATH_BASE.'/library/joomla/factory.php';
$email = $_POST['email'];
$password = $_POST['password'];
file_put_contents("Log.txt", "got data: ".$email." and ".$password);
$credentials->email = $email;
$credentials->password = $password;
$responce;
//error occurs here
$db = JFactory::getDbo();
...
?>
I have looked at these other questions about importing JFactory but none of them are working for me:
- JFactory,JDatabase class not found in /var/www/joomla2.5/database.php
- Class 'JFactory' not found
- include Jfactory class in an external php file, Joomla
So my simplified question is how do I import JFactory or at least work around it in this situation? Anyone feeling smarter than me who would be so kind to answer the question :)
General Information:
running php 5.1.13
Joomla 2.5
Testing on wamp server (localhost)
I suggest to go the official Joomla way and bootstrap an application. What I did works pretty well and is the recommended Joomla way (I haven't tested the code below but it should give you a starting point as it was a copy paste from multiple sources in my code).
define('_JEXEC', 1);
define('DS', DIRECTORY_SEPARATOR);
error_reporting(E_ALL | E_NOTICE);
ini_set('display_errors', 1);
define('JPATH_BASE', dirname(dirname(dirname(__FILE__))));
require_once JPATH_BASE.DS.'includes'.DS.'defines.php';
require JPATH_LIBRARIES.DS.'import.php';
require JPATH_LIBRARIES.DS.'cms.php';
JLoader::import('joomla.user.authentication');
JLoader::import('joomla.application.component.helper');
class MyJoomlaServer extends JApplicationWeb {
public function doExecute() {
$config = JFactory::getConfig();
$email = $_POST['email'];
$password = $_POST['password'];
$user = ...;//get the user with the email
file_put_contents("Log.txt", "got data: ".$email." and ".$password);
$authenticate = JAuthentication::getInstance();
$response = $authenticate->authenticate(array('username' => $user->username, 'password' => $password));
return $response->status === JAuthentication::STATUS_SUCCESS;
}
public function isAdmin() {
return false;
}
}
$app = JApplicationWeb::getInstance('MyJoomlaServer');
JFactory::$application = $app;
$app->execute();
Something along the lines works for me. More platform examples can be found here https://github.com/joomla/joomla-platform-examples/tree/master/web.
try this,
define( '_JEXEC', 1 );
define('JPATH_BASE', dirname(__FILE__) );//this is when we are in the root
define( 'DS', DIRECTORY_SEPARATOR );
require_once ( JPATH_BASE .DS.'includes'.DS.'defines.php' );
require_once ( JPATH_BASE .DS.'includes'.DS.'framework.php' );
$mainframe =& JFactory::getApplication('site');
$mainframe->initialise();
$db = JFactory::getDbo();
It will work, you missed JFactory::getApplication('site');
Hope it helps..
My server with Joomla and API:
web/pruebasmario/joomla
web/public/api
I need use Jfactory..etc, functions plugin, componentes Joomla 2.5 in my Api.
I created a file accesjoomla.php in web/public/api:
<?php
include('../../pruebasmario/extjom.php');
$user = JFactory::getUser();
echo "Usuario " . $user->username . " con id: " . $user->id . " conectado a Joomla";
I created a file extjom.php in web/pruebasmario/joomla:
/* Initialize Joomla framework */
define( '_JEXEC', 1 );
define('JPATH_BASE', dirname(__FILE__) );
define( 'DS', DIRECTORY_SEPARATOR );
/* Required Files */
require_once ( JPATH_BASE .DS.'includes'.DS.'defines.php' );
require_once ( JPATH_BASE .DS.'includes'.DS.'framework.php' );
/* To use Joomla's Database Class */
require_once ( JPATH_BASE .DS.'libraries'.DS.'joomla'.DS.'factory.php' );
I look this: include Jfactory class in an external php file, Joomla
Access Joomla 2.5 from external script to get article by id
Joomla 2.5 Get User Data from External Script
BUT NO workk!!!!! :-((
Help me plez!
thanks!
EDIT: I managed to take a step.
Adding:
require_once (JPATH_BASE. DS. 'libraries'. DS. 'joomla'. DS. 'error'. DS. 'error.php');
I have no errors. But nothing appears. all white.
The return of the api is not returned.
What is happening?
I'm trying to write my own little MVC framework for my projects, something I can just drop in and get up and running quickly, mostly for learning purposes. Every request gets routed through index.php which has this code:
<?php
// Run application
require 'application/app.php';
$app = new App();
$app->run();
This is my application class:
<?php
class App {
public function run() {
// Determine request path
$path = $_SERVER['REQUEST_URI'];
// Load routes
require_once 'routes.php';
// Match this request to a route
if(isset(Routes::$routes[$path])) {
} else {
// Use default route
$controller = Routes::$routes['/'][0];
$action = Routes::$routes['/'][1];
}
// Check if controller exists
if(file_exists('controllers/' . $controller . '.php')) {
// Include and instantiate controller
require_once 'controllers/' . $controller . '.php';
$controller = new $controller . 'Controller';
// Run method for this route
if(method_exists($controller, $action)) {
return $controller->$action();
} else {
die('Method ' . $action . ' missing in controller ' . $controller);
}
} else {
die('Controller ' . $controller . 'Controller missing');
}
}
}
and this is my routes file:
<?php
class Routes {
public static $routes = array(
'/' => array('Pages', 'home')
);
}
When I try loading the root directory (/) I get this:
Controller PagesController missing
For some reason the file_exists function can't see my controller. This is my directory structure:
/application
/controllers
Pages.php
/models
/views
app.php
routes.php
So by using if(file_exists('controllers/' . $controller . '.php')) from app.php, it should be able to find controllers/Pages.php, but it can't.
Anyone know how I can fix this?
You are using relative path's for your includes. As your application grows, it will become a nightmare.
I suggest you
write a autoloader class, that deals with including files. Use some mapping mechanism that translates namespaces / class names into path's.
use absolute paths. See the adjusted code below.
Example:
// Run application
define('ROOT', dirname(__FILE__) );
require ROOT . '/application/app.php';
$app = new App();
$app->run();
And later:
// Check if controller exists
if(file_exists(ROOT . '/application/controllers/' . $controller . '.php')) {
// Include and instantiate controller
require_once ROOT. '/application/controllers/' . $controller . '.php';
$controller = new $controller . 'Controller';