my class structure is as followed:
myproject
|
-------src (namespace PicoCore;)
|
-----objects (namespace PicoCore\Objects;)
-----tests (namespace PicoCore\Tests;)
I've created composer.json from autoloading:
{
"autoload": {
"psr-0": {
"PicoCore": "src",
"PicoCore\\Objects" : "src/objects",
"PicoCore\\Tests" : "src/tests"
}
}
}
I've created a testing script after installing:
<?php
require_once "../../vendor/autoload.php";
use PicoCore\Objects\User;
$user = new User();
$user->name = "asaf";
echo $user->name;
?>
User Class:
<?php
/**
* Created by PhpStorm.
* User: avivpaz
* Date: 12/25/14
* Time: 12:07 PM
*/
namespace PicoCore\Objects;
class User extends APIUser implements ConvertibleObjects
{
/**
* #var string User's Name
*/
public $name;
/**
* #var string User's Push Id
*/
public $pushId;
/**
* #var UserDevice User's device type
*/
public $userDevice;
/**
* #var double The location latitude
*/
public $latitude;
/**
* #var double The location longitude
*/
public $longitude;
public function __construct()
{
$this->label = USER_LABEL;
}
/**
* init with APIUser
* #param $APIUser APIUser
* #return User type
*/
public static function withAPIUser($APIUser)
{
$user = new User();
$user->label=USER_LABEL;
$user->id = $APIUser->id;
$user->facebookAccessToken = $APIUser->facebookAccessToken;
$user->picoAccessToken = $APIUser->picoAccessToken;
$user->accessTokenExpires = $APIUser->accessTokenExpires;
return $user;
}
public function ConvertObjectToCypherSyntax()
{
return '{id:"' . $this->id . '",name:"' . $this->name . '",picoAccessToken:"' . $this->picoAccessToken . '",accessTokenExpires:"' . $this->accessTokenExpires->getTimestamp() . '",latitude:' . $this->latitude . ',longitude:' . $this->longitude . '}';
}
static public function ConvertNodeToObject($results)
{
$user = new User();
if (is_null($results))
return $user;
$user->id = $results->getProperty('id');
$user->name = $results->getProperty('name');
$user->picoAccessToken = $results->getProperty('picoAccessToken');
$user->latitude = $results->getProperty('latitude');
$user->longitude = $results->getProperty('longitude');
// $user->userDevice = UserDevice::ConvertNodeToObject($results['userDevice']);
if (!$results->getProperty('accessTokenExpires') == "")
$user->accessTokenExpires = getDateTimeFromTimeStamp($results->getProperty('accessTokenExpires'));
return $user;
}
static public function ConvertArrayToObject($array) {
$user = new User();
if (array_key_exists("id", $array))
$user->id = $array["id"];
if (array_key_exists("name", $array))
$user->name = $array["name"];
if (array_key_exists("pico_access_token", $array))
$user->picoAcceessToken = $array["pico_access_token"];
if (array_key_exists("access_token_expires", $array))
$user->accessTokenExpires = getDateTimeFromString($array["access_token_expires"]);
if (array_key_exists("device_type", $array))
$user->deviceType = $array["device_type"];
if (array_key_exists("latitude", $array))
$user->latitude = $array["latitude"];
if (array_key_exists("longitude", $array))
$user->longitude = $array["longitude"];
if (array_key_exists("userDevice", $array))
$user->userDevice = UserDevice::ConvertArrayToObject($array["userDevice"]);
return $user;
}
public function toArray()
{
$user = array();
if (!empty($this->id))
$user["id"] = $this->id;
if (!empty($this->name))
$user["name"] = urldecode($this->name);
if (!empty($this->picoAccessToken))
$user["pico_access_token"] = $this->picoAccessToken;
if (!empty($this->accessTokenExpires))
$user["access_token_expires"] = getMysqlDateTime($this->accessTokenExpires);
if (!empty($this->latitude))
$user["latitude"] = $this->latitude;
if (!empty($this->longitude))
$user["longitude"] = $this->longitude;
if (isset($this->userDevice)) {
$userDevice = $this->userDevice->toArray();
if (!empty($userDevice))
$user["userDevice"] = $userDevice;
}
if (count($user) > 0)
return $user;
return null;
}
}
I get a can't find class exception.. any ideas ?
With PSR-0
In order to use PSR-0, you need to change your structure layout to:
src/
└── PicoCore
├── Objects
│ └── User.php
└── Tests
And in your composer.json you need to add PicoCore namespace:
"psr-0": {
"PicoCore\\": "src"
}
Alternative with PSR-4
If you want to keep your current file system layout, you can use PSR-4 instead of PSR-0. In order to use PSR-4, you need to update composer.json:
"autoload": {
"psr-4": {
"PicoCore\\": "src",
"PicoCore\\Objects\\" : "src/objects",
"PicoCore\\Tests\\" : "src/tests"
}
}
After you made your changes, run composer dumpautoload to regenerate autoload files.
If it's a namespace without class, it's must finish with \\
So :
"autoload": {
"psr-0": {
"PicoCore\\": "src",
"PicoCore\\Objects\\" : "src/objects",
"PicoCore\\Tests\\" : "src/tests"
}
}
and check file autoload
composer/autoload_namespaces.php
see https://getcomposer.org/doc/04-schema.md#psr-0
Related
I instantiate my classes through custom functions.
The classes are in app/code/core/ e.g.
app/code/core/Property/Helper/Property.php
require_once("Core/Helper.php");
class Property_Helper_Property extends Core\Helper
{
public function __construct($con)
{
parent::__construct($con);
}
public function test()
{
return "hello";
}
}
app/code/core/Core/Helper.php
<?php
namespace Core;
abstract class Helper
{
protected $con;
public function __construct($con)
{
$this->con = $con;
}
}
I can call the method test() of the class Property_Helper_Property from any file like this:
require_once 'app/Main.php'; // always needed
Main::getHelper("Property/Property")->test();
app/Main.php
This file contains the final class "Main" which has the static method getHelper
if (!defined('DS')) define('DS', DIRECTORY_SEPARATOR);
if (!defined('PS')) define('PS', PATH_SEPARATOR);
if (!defined('BP')) define('BP', dirname(dirname(__FILE__)));
/**
* Set include path
*/
Main::register('original_include_path', get_include_path());
$paths = array();
$paths[] = Main::CORE_PATH;
$paths[] = Main::LOCAL_PATH;
$paths[] = BP . DS . 'lib';
$paths[] = BP . DS . 'inc';
$appPath = implode(PS, $paths);
set_include_path($appPath . PS . Main::registry('original_include_path'));
final class Main
{
const CORE_PATH = BP . DS . 'app' . DS . 'code' . DS . 'core';
const LOCAL_PATH = BP . DS . 'app' . DS . 'code' . DS . 'local';
/**
* Registry collection
*
* #var array
*/
static private $_registry = array();
public static function getDbConnection()
{
return self::registry("db_connection");
}
/**
* Register a new variable
*
* #param string $key
* #param mixed $value
* #param bool $graceful
*/
public static function register($key, $value, $graceful = false)
{
if (isset(self::$_registry[$key])) {
if ($graceful) {
return;
}
self::throwException('Main registry key "'.$key.'" already exists');
}
self::$_registry[$key] = $value;
}
/**
* Unregister a variable from register by key
*
* #param string $key
*/
public static function unregister($key)
{
if (isset(self::$_registry[$key])) {
if (is_object(self::$_registry[$key]) && (method_exists(self::$_registry[$key], '__destruct'))) {
self::$_registry[$key]->__destruct();
}
unset(self::$_registry[$key]);
}
}
/**
* Retrieve a value from registry by a key
*
* #param string $key
* #return mixed
*/
public static function registry($key)
{
if (isset(self::$_registry[$key])) {
return self::$_registry[$key];
}
return null;
}
public static function getHelper($name)
{
$classPath = self::getClassPath($name, "Helper");
if (!$classPath) { return false; }
$fullClassPath = self::getFullClassPath($classPath);
if (!$fullClassPath) { return false; }
$obj = self::getClassInstance($fullClassPath, $classPath);
if (!$obj) { return false; }
return $obj;
}
public static function getModel($name)
{
$classPath = self::getClassPath($name, "Model");
if (!$classPath) { return false; }
$fullClassPath = self::getFullClassPath($classPath);
if (!$fullClassPath) { return false; }
$obj = self::getClassInstance($fullClassPath, $classPath);
if (!$obj) { return false; }
return $obj;
}
private function getClassInstance($fullClassPath, $classPath)
{
if (!$classPath) { return false; }
require_once($fullClassPath);
$className = str_replace("/", "_", $classPath);
if (class_exists($className)) {
return new $className(self::getDbConnection());
} else {
return false;
}
}
private function getFullClassPath($classPath)
{
$modulPaths = [self::CORE_PATH, self::LOCAL_PATH];
return self::checkIfFileExistInModule($modulPaths, $classPath);
}
private function getClassPath($modelName, $identifier="Model")
{
if (strpos($modelName, '/') === false) { return false; }
if (substr_count($modelName, "/") == 1) {
$exp = explode("/", $modelName);
return $exp[0] . "/$identifier/" . $exp[1];
} else {
return false;
}
}
private function checkIfFileExistInModule($modulPaths, $modelname)
{
foreach($modulPaths as $path) {
$path = $path . DS . $modelname . ".php";
if (file_exists($path)) {
return $path;
}
}
return "0";
}
}
This works just fine... now the actual question.
If I am writing...
$obj = Main::getHelper("Property/Property");
$obj->
...then my IDE (NetBeans) does not auto suggest the public methods/properties which I can use.
Is there a way to "teach" my logic to add auto suggestion / auto completion so that it automatically shows all public methods/properties available in the object?
You need to use phpdoc blocks. Pretty sure they are supported by NetBeans:
/** #var Property_Helper_Property $obj */
$obj = Main::getHelper("Property/Property");
From that point forward auto-completion and static analysis will work, since it will be understood that $obj will be an instance of Property_Helper_Property.
I'm trying to include a PHP class in magento 2.
I use a require_once and create a folder lib in the root of my module and there I put the folder that contains the class 'lib / Meli / Meli.php'
Also try in the project folder 'lib / lib_web / Meli / Meli.php'
All without success, any suggestion
This is my controller 'Controller / Adminhtml / Action / publicar.php'
<?php
namespace Uno\MercadoLibre\Controller\Adminhtml\Action;
use \Magento\Backend\App\Action;
class publicar extends Action {
protected $_session;
protected $_filesystem;
protected $_directoryList;
/**
* #param Action\Context $context
*/
public function __construct(
Action\Context $context,
\Magento\Framework\Filesystem\DirectoryList $directoryList,
\Magento\Framework\Filesystem $filesystem,
\Magento\Customer\Model\Session $session
) {
parent::__construct($context);
$this->_directoryList = $directoryList;
$this->_filesystem = $filesystem;
$this->_session = $session;
}
/**
* {#inheritdoc}
*/
protected function _isAllowed() {
return $this->_authorization->isAllowed('Uno_MercadoLibre::action_publicar');
}
/**
* Publicar action
*
* #return \Magento\Framework\Controller\ResultInterface
*/
public function execute() {
$appId = '123';
$secretKey = 'abcdefghijkl';
$redirectURI = 'https://example.mx';
$siteId = 'MLM';
//$path = $this->_directoryList->getPath('lib_web');
//echo "PATH " . $path.'/Meli/Meli.php';
//require_once($path.'/Meli/Meli.php');
//$libPath = $this->_filesystem->getDirectoryRead(\Magento\Framework\App\Filesystem\DirectoryList::LIB)->getAbsolutePath();
$mediapath = $this->_filesystem->getDirectoryRead(\Magento\Framework\App\Filesystem\DirectoryList::APP)->getAbsolutePath();
$modulePath = $mediapath.'code/Uno/MecadoLibre/lib/Meli/Meli.php';
echo $modulePath;
require_once($modulePath);
$meli = new Meli($appId, $secretKey);
$params = array();
$url = '/sites/' . $siteId;
$result = $meli->get($url, $params);
echo '<pre>';
print_r($result);
echo '</pre>';
die();
}
}
?>
the path of the class returns to me, but it does not help me for the require_once
/var/inetpub/example.mx/app/code/Uno/MecadoLibre/lib/Meli/Meli.php
I think the solution of your problem the composer.
Please check it the accepted answer:
How to I use Composer to autoload classes from outside the vendor?
Thank you, your information, I told you how I resolved this.
In my class Meli.php add:
namespace Uno\MercadoLibre\Controller\Adminhtml\Action;
In my controller add:
use \Uno\MercadoLibre\Lib\Meli\Meli;
Object Manager
$objectManager = \Magento\Framework\App\ObjectManager::getInstance(); $ml_session = $ objectManager->create('\Uno\MercadoLibre\Lib\Meli\Meli', ['client_id' => $ appId, 'client_secret' => $ secretKey, 'access_token' => $ accessToken]);
I try to load all the routes from all Bundles in a specific namespace dynamically. So I set up a CustomRoute Loader as a service and determine there which route to add. But the PhpFileLoader can´t find the Bundle. I get the name of thee Bundles with $this->container->getParameter('kernel.bundles'); so there can´t be a typo. Loading these Bundles hardcoded from within the routing.php works fine but not from the service class. Inside of the routing.php I can´t determine with Bundles are loaded, so using only the routing.php is not a solution. What do I miss? This is my code so far:
Routing.php
<?php
// app/config/routing.php
use Symfony\Component\Routing\Route;
use Symfony\Component\Routing\RouteCollection;
$path = "/Controller/";
$defaultAnnotationRoutes = [
'SomeDefaultBundle'];
$routes = new RouteCollection();
$routes->add('somedefaulRoute', new Route('/', array(
'_controller' => 'SomeDefaultBundle:Welcome:page',
)));
$routes->addCollection(
$loader->import("#FOSJsRoutingBundle/Resources/config/routing/routing.xml"
));
foreach ($defaultAnnotationRoutes as $bundleName) {
$routingConfigPath = "#" . $bundleName . $path;
$routes->addCollection(
// loads routes from the given routing file stored in some bundle
$loader->import($routingConfigPath, "annotation"));
}
$routes->addCollection(
$loader->import('mapbender.routing_loader:load', "service"));
return $routes;
ServiceClass:
namespace Mapbender\CoreBundle\Routing;
use Symfony\Component\Config\Exception\FileLoaderImportCircularReferenceException;
use Symfony\Component\Config\Exception\FileLoaderLoadException;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\Routing\Loader\PhpFileLoader;
use Symfony\Component\Routing\RouteCollection;
class BundleLoader
{
protected $container;
protected $path = "/Controller/";
protected $loader;
/**
* BundleLoader constructor.
*
* #param $container
*/
public function __construct($container)
{
$this->container = $container;
$rootdir = $this->container->get('kernel')->getRootDir();
$this->loader = new PhpFileLoader(new FileLocator());
}
/**
* #param $resource
* #param null $type
* #return RouteCollection
*/
public function load($resource, $type = null)
{
$routes = new RouteCollection();
$bundles = $this->container->getParameter('kernel.bundles');
foreach ($bundles as $bundleName => $bundlePath) {
if (preg_match('/CompanyVendor/', $bundleName, $matches)) {
$routingConfigPath = "#" . $bundleName. $this->path;
try {
$routes->addCollection(
$this->loader->import($routingConfigPath)
);
} catch (FileLoaderImportCircularReferenceException $e) {
throw $e;
} catch (FileLoaderLoadException $e) {
throw $e;
}
}
}
return $routes;
}
}
i have created a joomla component and when i click on publish and unpublish button in admin then i am getting such error.
Fatal error: Call to a member function publish() on boolean in ...\libraries\legacy\controller\admin.php on line 209
Please help
UPDATE
my View.html.php
require_once JPATH_COMPONENT . '/helpers/lab.php';
class labViewStructurelist extends JViewLegacy
{
protected $structurelist;
protected $pagination;
public $filterForm;
public $activeFilters;public $state;
public function display($tpl = null)
{
$this->structurelist = $this->get('Items');
$this->pagination = $this->get('Pagination');
$this->state = $this->get('State');
//print_r($this->pagination->pagesTotal);die();
$this->filterForm = $this->get('FilterForm');
$this->activeFilters = $this->get('ActiveFilters');
$this->addToolBar();
$this->sidebar = JHtmlSidebar::render();
if (count($errors = $this->get('Errors')))
{
JError::raiseError(500, implode('<br />', $errors));
return false;
}
return parent::display($tpl);
}
protected function addToolBar() {
JToolBarHelper::title( JText::_('COM_LAB_LAB_DDDD'), 'generic.png' );
JToolBarHelper::publish('Structurelist.publish');
JToolBarHelper::unpublish('Structurelist.unpublish');
JToolBarHelper::deleteList('', 'patients.delete', 'JTOOLBAR_DELETE');
JToolBarHelper::preferences('com_lab');
}
}
Controller/stricturelist.php
// No direct access to this file
defined('_JEXEC') or die('Restricted access');
// import Joomla controller library
jimport('joomla.application.component.controlleradmin');
class LabControllerStructurelist extends JControllerAdmin
{
public function getModel($name='Structurelist',$prefix='ssModel',$config=array('ignore_request'=>true))
{
$model=parent::getModel($name,$prefix,$config);
return $model;
}
}
models\structurelist.php
defined('_JEXEC') or die;
jimport('joomla.application.component.modellist');
JFormHelper::loadFieldClass('list');
class LabModelStructurelist extends JModelList{
public function __construct($config = array())
{
if (empty($config['filter_fields']))
{
$config['filter_fields'] = array(
'id', 'a.id',
'fullname', 'a.fullname',
);
$assoc = JLanguageAssociations::isEnabled();
if ($assoc)
{
$config['filter_fields'][] = 'association';
}
}
parent::__construct($config);
}
public function getListQuery()
{
$db = JFactory::getDbo();
$query = $db->getQuery(true);
$query->select('*');
$query->from('#__ss_structure_tmp');
$search = $this->getState('filter.search');
$limit = $this->getState('filter.limit');
if (!empty($search)) {
$query->where('fullname LIKE "%' . $search .'%" ' );
}
if (!empty($limit)) {
$query->setLimit($limit);
}
return $query;
}
protected function populateState($ordering = 'a.fullname', $direction = 'asc')
{
$app = JFactory::getApplication();
if ($layout = $app->input->get('layout'))
{
$this->context .= '.' . $layout;
}
$search = $this->getUserStateFromRequest($this->context . '.filter.search', 'filter_search');
$this->setState('filter.search', $search);
parent::populateState();
}
}
You need to provide the model to your controller using the getModel() method. Look in the articles controller of the com_content for example.
You need to add a table file with the publish function within:
defined('_JEXEC') or die;
use Joomla\Utilities\ArrayHelper;
class labTableStructurelist extends JTable
{
/**
* Constructor
*
* #param JDatabase &$db A database connector object
*/
public function __construct(&$db)
{
parent::__construct('#__ss_structure_tmp', 'id', $db);
}
/**
* Overloaded bind function to pre-process the params.
*
* #param array $array Named array
* #param mixed $ignore Optional array or list of parameters to ignore
*
* #return null|string null is operation was satisfactory, otherwise returns an error
*
* #see JTable:bind
* #since 1.5
*/
public function bind($array, $ignore = '')
{
$input = JFactory::getApplication()->input;
$task = $input->getString('task', '');
if (($task == 'save' || $task == 'apply') && (!JFactory::getUser()->authorise('core.edit.state', 'com_lab.structurelist.'.$array['id']) && $array['state'] == 1))
{
$array['state'] = 0;
}
if ($array['id'] == 0)
{
$array['created_by'] = JFactory::getUser()->id;
}
if (isset($array['params']) && is_array($array['params']))
{
$registry = new JRegistry;
$registry->loadArray($array['params']);
$array['params'] = (string) $registry;
}
if (isset($array['metadata']) && is_array($array['metadata']))
{
$registry = new JRegistry;
$registry->loadArray($array['metadata']);
$array['metadata'] = (string) $registry;
}
if (!JFactory::getUser()->authorise('core.admin', 'com_lab.structurelist.' . $array['id']))
{
$actions = JAccess::getActionsFromFile(
JPATH_ADMINISTRATOR . '/components/com_lab/access.xml',
"/access/section[#name='user']/"
);
$default_actions = JAccess::getAssetRules('com_lab.structurelist.' . $array['id'])->getData();
$array_jaccess = array();
foreach ($actions as $action)
{
$array_jaccess[$action->name] = $default_actions[$action->name];
}
$array['rules'] = $this->JAccessRulestoArray($array_jaccess);
}
// Bind the rules for ACL where supported.
if (isset($array['rules']) && is_array($array['rules']))
{
$this->setRules($array['rules']);
}
return parent::bind($array, $ignore);
}
/**
* This function convert an array of JAccessRule objects into an rules array.
*
* #param array $jaccessrules An array of JAccessRule objects.
*
* #return array
*/
private function JAccessRulestoArray($jaccessrules)
{
$rules = array();
foreach ($jaccessrules as $action => $jaccess)
{
$actions = array();
foreach ($jaccess->getData() as $group => $allow)
{
$actions[$group] = ((bool) $allow);
}
$rules[$action] = $actions;
}
return $rules;
}
/**
* Overloaded check function
*
* #return bool
*/
public function check()
{
// If there is an ordering column and this is a new row then get the next ordering value
if (property_exists($this, 'ordering') && $this->id == 0)
{
$this->ordering = self::getNextOrder();
}
return parent::check();
}
/**
* Method to set the publishing state for a row or list of rows in the database
* table. The method respects checked out rows by other users and will attempt
* to checkin rows that it can after adjustments are made.
*
* #param mixed $pks An optional array of primary key values to update. If not
* set the instance property value is used.
* #param integer $state The publishing state. eg. [0 = unpublished, 1 = published]
* #param integer $userId The user id of the user performing the operation.
*
* #return boolean True on success.
*
* #since 1.0.4
*
* #throws Exception
*/
public function publish($pks = null, $state = 1, $userId = 0)
{
// Initialise variables.
$k = $this->_tbl_key;
// Sanitize input.
ArrayHelper::toInteger($pks);
$userId = (int) $userId;
$state = (int) $state;
// If there are no primary keys set check to see if the instance key is set.
if (empty($pks))
{
if ($this->$k)
{
$pks = array($this->$k);
}
// Nothing to set publishing state on, return false.
else
{
throw new Exception(500, JText::_('JLIB_DATABASE_ERROR_NO_ROWS_SELECTED'));
}
}
// Build the WHERE clause for the primary keys.
$where = $k . '=' . implode(' OR ' . $k . '=', $pks);
// Determine if there is checkin support for the table.
if (!property_exists($this, 'checked_out') || !property_exists($this, 'checked_out_time'))
{
$checkin = '';
}
else
{
$checkin = ' AND (checked_out = 0 OR checked_out = ' . (int) $userId . ')';
}
// Update the publishing state for rows with the given primary keys.
$this->_db->setQuery(
'UPDATE `' . $this->_tbl . '`' .
' SET `state` = ' . (int) $state .
' WHERE (' . $where . ')' .
$checkin
);
$this->_db->execute();
// If checkin is supported and all rows were adjusted, check them in.
if ($checkin && (count($pks) == $this->_db->getAffectedRows()))
{
// Checkin each row.
foreach ($pks as $pk)
{
$this->checkin($pk);
}
}
// If the JTable instance value is in the list of primary keys that were set, set the instance.
if (in_array($this->$k, $pks))
{
$this->state = $state;
}
return true;
}
/**
* Define a namespaced asset name for inclusion in the #__assets table
*
* #return string The asset name
*
* #see JTable::_getAssetName
*/
protected function _getAssetName()
{
$k = $this->_tbl_key;
return 'com_lab.structurelist.' . (int) $this->$k;
}
/**
* Returns the parent asset's id. If you have a tree structure, retrieve the parent's id using the external key field
*
* #param JTable $table Table name
* #param integer $id Id
*
* #see JTable::_getAssetParentId
*
* #return mixed The id on success, false on failure.
*/
protected function _getAssetParentId(JTable $table = null, $id = null)
{
// We will retrieve the parent-asset from the Asset-table
$assetParent = JTable::getInstance('Asset');
// Default: if no asset-parent can be found we take the global asset
$assetParentId = $assetParent->getRootId();
// The item has the component as asset-parent
$assetParent->loadByName('com_lab');
// Return the found asset-parent-id
if ($assetParent->id)
{
$assetParentId = $assetParent->id;
}
return $assetParentId;
}
/**
* Delete a record by id
*
* #param mixed $pk Primary key value to delete. Optional
*
* #return bool
*/
public function delete($pk = null)
{
$this->load($pk);
$result = parent::delete($pk);
return $result;
}
}
Please note, that this is just an example of a table file, I can't guarantee that this would work just by copy&paste. Please check com_content/table for another example.
Also add a getTable() to your List single item model:
public function getTable($type = 'view_name', $prefix = 'labTable', $config = array())
{
return JTable::getInstance($type, $prefix, $config);
}
Please check if file structure is correct:
List View
structurelist**s** -> list view with multiple items
|-> controller/structurelists.php
|-> models/structurelists.php
|-> view/structurelists/
Single View / List View (publish() for example)
structurelist -> single item view (edit view)
|-> models/structurelist.php (this is important for the publish() in the list view)
|-> models/forms/structurelist.xml
|-> tables/structurelist.php (this is important for the publish() in the list view)
|-> view/structurelist/
Feel free to comment if you need more help.
Its the first time working with an autoloader and getting some errors.
The structure is as follows:
AnimalShop (root)
classes
Shop.php
index.php
I have the following simple code
Index.php
<?php
spl_autoload_register(function ($class_name)
{
include $class_name . '.php';
});
echo "<h1>PETs SHOP</h1>";
// Create a shop
$shop = new Shop();
Shop is a simple class
<?php
namespace PHPAdvanced\AnimalShop\classes;
/*
* Pet shop
*/
class Shop
{
/**
* #var Pets[] pets
*/
private $pets = [];
public function addPetsToArray(Pets $pet)
{
$this->pets[] = $pet;
}
/**
* Print pets naam
*/
public function printPets()
{
foreach($this->pets as $pet)
{
echo "<p>" . $pet->getPetNaam() . "</p>";
}
}
}
When i run index.php i get the following errors:
Warning: include(Shop.php): failed to open stream: No such file or directory in /var/www/phpadvancedCourse/AnimalShop/index.php on line 4
Warning: include(): Failed opening 'Shop.php' for inclusion (include_path='.:/usr/share/php:') in /var/www/phpadvancedCourse/AnimalShop/index.php on line 4
spl_autoload_register(function ($class_name)
{
include realpath(dirname(__FILE__))."/classes/".$class_name . '.php';
});
your path is wrong.. try this..
To solve the problem i have used PSR-4 autoloading through composer with the following structure and code.
Structure
AnimalShop (root)
index.php
App (Folder)
Behavior (Folder)
WalkBehavior.php (interface)
Pets(Folder)
Cat.php
Dog.php
Fish.php
Pets.php (abstract class)
Shop(Folder)
PetShop.php
Composer.json
{
"autoload" : {
"psr-4" : {
"App\\" : "App"
}
}
}
index.php
<?php
// Autoload
require "vendor/autoload.php";
use App\Shop\PetShop;
use App\Pets\Dog;
use App\Pets\Fish;
use App\Pets\Cat;
echo "<h1>PETs SHOP</h1>";
// Create a shop
$shop = new PetShop();
$shop->addPetsToArray(new Dog("Yuki"));
$shop->addPetsToArray(new Fish("BLubie"));
$shop->addPetsToArray(new Cat("Cattie"));
$shop->printPets();
Example of Petshop and Dog
<?php
namespace App\Shop;
use App\Pets\Pets;
/*
* Pet shop
*/
class PetShop
{
/**
* #var Pets[] pets
*/
private $pets = [];
public function addPetsToArray(Pets $pet)
{
$this->pets[] = $pet;
}
/**
* Print pets naam
*/
public function printPets()
{
foreach($this->pets as $pet)
{
echo "<p>" . $pet->getPetNaam() . "</p>";
}
}
}
DOG
<?php
namespace App\Pets;
/**
* Class Dog
*/
class Dog extends Pets
{
/**
* Dog constructor.
*
* #param $name
*/
public function __construct(string $name)
{
parent::__construct($name);
}
public function walk() : string
{
return "Dog is walking";
}
}