I'm working on a site from scratch. Partially as practice and to help a friend. One of the things I'm doing is creating the menu dynamically off of plugins and modules that we create. My current config defines the base files and then the user plugin is supposed to be able to push more data into the array.
What I have currently is
<?php
function Deny() {
if(!defined("__directaccess")) {
header("Location: /");
}
}
Deny();
$Plugins = array("Bootstrap", "MySQL", "User");
$menuItems = array (
"Home" => "/",
);
And that's inside my config.php file.
Within my User.class.php file which is successfully loaded with the plugin loader I've built I have
require_once(__root.'/config.php');
$menu = array (
"User Panel" => "/index.php?page=user",
"Logout" => "/index.php?page=login&module=logout",
);
print_r($menuItems);
$menuItems Gives that it's not defined.
I've checked with a simple echo "Included"; script inside the config.php file to ensure that it's being included, but at the $menuItems we fail out. What I want to happen is after the Menu has been generated I'll be able to push more data into the menuItems array so that modules/plugins can add to the menu as well and use variables within those functions to make the navigation seamless. Any help would be appreciated as I'm stumped as I don't understand why it can't access the array.
Load order to help see what's going on
index.php
LoadPlugins($Plugins);
LoadModule("TopNav");
LoadPages();
loader.php
session_start();
define("__directaccess", true);
require_once("config.php");
//Loads All Class Functions
function LoadClasses() {
foreach(glob(__class.'/*.class.php') as $class) {
if(file_exists($class)) {
require_once($class);
}
}
}
function LoadPlugins($Plugins) {
foreach($Plugins as $Plugin) {
LoadPlugin($Plugin);
}
}
function LoadPages() {
if(isset($_GET['page'])) {
if(file_exists(__root. '/includes/' . $_GET['page'] . '.php')) {
require_once(__root. '/includes/' . $_GET['page'] . '.php');
} else {
echo "Page not Found"; //Make a 404 Error Page
}
}
if(!isset($_GET['page'])) {
if(file_exists(__root . '/includes/homepage.php')) {
require_once(__root . '/includes/homepage.php');
}
}
}
function LoadModule($moduleName, $page="index") {
$path = __modules . '/' . $moduleName . '/' . $page . '.php';
if(file_exists($path)) {
require_once($path);
} else {
echo "Failed to Load module " . $moduleName;
}
}
function LoadPlugin($pluginName) {
$path = __plugins . '/' . $pluginName . '/' . $pluginName . '.class.php';
if(file_exists($path)) {
require_once($path);
} else {
echo "Failed to load plugin " . $pluginName;
}
}
The $menuItems array is first created in the config.php file and then the plugins are loaded. The thought is that the plugins should be able to access variables from within the config.php file with that format.
Full User.class.php
$menu = array (
"User Panel" => "/index.php?page=user",
"Logout" => "/index.php?page=login&module=logout",
);
print_r($menuItems);
function __isOnline() {
if(isset($_SESSION['username'])) {
return true;
} else {
return false;
}
}
class UserFunctions extends webConn {
public function userDetails($arg, $username) {
$query = <<<SQL
SELECT * FROM account WHERE username = :username
SQL;
$resource = $this->db->prepare( $query );
$resource->execute( array (
":username" => $username,
));
$result = $resource->fetch(PDO::FETCH_ASSOC);
return $result[$arg];
}
}
$userFunction = new UserFunctions();
config.php with SQL Database info Removed
<?php
function Deny() {
if(!defined("__directaccess")) {
header("Location: /");
exit();
}
}
//Deny();
$Plugins = array("Bootstrap", "MySQL", "User");
$menuItems = array (
"Home" => "/",
);
//Create a root directory base name to reference
define('__root', dirname(__file__));
//Create Class Reference Global Variable
define('__class', __root . '/classes');
//Create Module reference
define('__modules', __root.'/modules');
//Create Plugin reference
define('__plugins', __root.'/plugins');
When you call require/include inside a function, the scope is the function itself.
For example the following function
function LoadClasses() {
require_once($class);
}
is equivalent to
function LoadClasses() {
print_r($menuItems);
}
That's why $menuItems is null. To fix the problem, you can use global keyword to always refer a global variable.
gloabl $menuItems;
print_r($menuItems);
Related
This question already has answers here:
PHP - Can't dynamcally instantiate class
(1 answer)
Using namespaces with classes created from a variable
(1 answer)
Closed 5 years ago.
I am trying to display a message from class Main, but the class cannot be found for some reason even though it is autoloaded at the beginning of my index.php
autoload.php
return array(
'App\\Http\\Controllers\\IndexController' => $baseDir . '/app/Http/Controllers/IndexController.php',
'App\\Http\\Controllers\\Main' => $baseDir . '/app/Http/Controllers/Main.php',
'App\\Http\\Core\\Controller' => $baseDir . '/app/Http/Core/Controller.php',
'App\\Http\\Core\\Error' => $baseDir . '/app/Http/Core/Error.php',
'App\\Http\\Core\\Load' => $baseDir . '/app/Http/Core/Load.php',
'App\\Http\\Core\\Route' => $baseDir . '/app/Http/Core/Route.php',
'App\\Http\\Core\\Url' => $baseDir . '/app/Http/Core/Url.php',
'App\\Http\\Database\\Database' => $baseDir . '/app/Http/Database/Database.php',
'App\\Http\\Database\\Model' => $baseDir . '/app/Http/Database/Model.php',
);
The class Main.php is located in directory app/Http/Controllers
Main.php
namespace App\Http\Controllers;
class Main
{
function index(){
echo "Main Index";
}
}
This instance of the class is created by my Route.php, but for now I am trying to load it directly in my index.php
index.php
namespace App\Http\Controllers;
use App\Http\Core\Route;
error_reporting(E_ALL);
ini_set("display_errors", 1);
require_once __DIR__ . '/../vendor/autoload.php';
if(class_exists("Main")){
echo "The class is found!";
} else {
echo "This class is not found";
}
new Route();
Here is the
Route.php
namespace App\Http\Core;
class Route
{
private $routes;
function __construct()
{
$this->routes = array();
$route = $this->findRoute();
if(class_exists(__NAMESPACE__ . '\\' . $route["controller"])){
$conroller = new $route["controller"]();
if(method_exists($conroller, $route["method"])){
$conroller->$route["method"]();
}else{
Error::show(404);
}
}else{
Error::show(404);
}
}
private function routePart($route){
if(is_array($route)){
$route = $route["url"];
}
$parts = explode("/", $route);
return $parts;
}
static function uri($part){
$parts = explode("/", $_SERVER["REQUEST_URI"]);
if($parts[1] == 'index.php'){
$part++;
}
return (isset($parts[$part])) ? $parts[$part] : "";
}
private function findRoute(){
foreach ($this->routes as $route){
$parts = $this->routePart($route);
$allMatch = true;
foreach ($parts as $key => $value){
if($value != "*"){
if(Route::uri($key) != $value){
$allMatch = false;
}
}
}
if($allMatch){
return $route;
}
}
$uri_1 = Route::uri(1);
$uri_2 = Route::uri(2);
if($uri_1 == ""){
$uri_1 = "Main";
}
if($uri_2 == ""){
$uri_2 = "index";
}
$route = array(
"controller" => $uri_1,
"method" => $uri_2
);
return $route;
}
}
Any hints will help, please
I'm trying to pass a working variable $count from a controller name dashboard which has authentication.. I tried to insert $this->Auth->allow('_getOnlineUsers'); so that none admin can use the function.
<?php
class DashboardsController extends AppController{
var $name = 'Dashboards';
var $uses = array('Bid', 'Account');
function beforeFilter(){
parent::beforeFilter();
if(!empty($this->Auth)) {
$this->Auth->allow('template_switch');
$this->Auth->allow('_getOnlineUsers');
}
}
function _getOnlineUsers(){
$dir = TMP . DS . 'cache' . DS;
$files = scandir($dir);
$count = 0;
foreach($files as $filename){
if(is_dir($dir . $filename)){
continue;
}
if(substr($filename, 0, 16) == 'cake_user_count_') {
$count++;
}
}
return $count;
}
then inside the same controller I pass the variable to onlineUsers
$this->set('onlineUsers', $this->_getOnlineUsers());
then in my user.ctp I tried the following
<?php echo $count;?>
<?php echo $onlineUsers;?>
nothing happened please help
does location make a difference? because here's my destinations
controller/dashboards_controller.php
/alberta_template/elements/user.ctp
On my codeigniter HMVC project. When I try to run my first isset statement in modules foreach section. If I uncomment the code below then, fire fox loads page error The connection was reset.
But if I comment out the code like below the page loads fine very strange.
//if (isset($part[0]) && $this->setting->get($part[0] . '_status')) {
// $data['modules'][] = Modules::run('catalog/module/'.$part[0].'/index');
//}
For some reason does not like using isset($part[0])
How code works
$part[0] it returns the module name example category
$part[1] it returns the module number example 66 category.66
$this->setting->get($part[0] . '_status') returns either 1 if
enabled or 0 if disabled.
What could be the cause of page not loading when I uncomment the code above. Any suggestions
Controller
<?php
class Column_left extends MX_Controller {
public function index() {
$this->load->model('catalog/extension/model_extension_extension');
$this->load->model('catalog/design/model_design_layout');
$route = $this->uri->segment(1).'/'.$this->uri->segment(2);
// $route outputs like pages/category
$layout_id = 0;
if (!$layout_id) {
$layout_id = $this->model_design_layout->get_layout($route);
}
if (!$layout_id) {
// Setting library autoloaded
$layout_id = $this->setting->get('config_layout_id');
}
$data['modules'] = array();
$modules = $this->model_design_layout->get_layout_modules($layout_id, 'column_left');
foreach ($modules as $module) {
$part = explode('.', $module['code']);
echo $part[0];
// Setting library autoloaded
if (isset($part[0]) && $this->setting->get($part[0] . '_status')) {
$data['modules'][] = Modules::run('catalog/module/'.$part[0].'/index');
}
if (isset($part[1])) {
$setting_info = $this->model_extension_module->get_module($part[1]);
if ($setting_info && $setting_info['status']) {
$data['modules'][] = Modules::run('catalog/module/'.$part[0].'/index', $setting_info);
}
}
}
// Setting library autoloaded
if (file_exists(DIR_TEMPLATE .$this->setting->get('config_template'). '/template/common/column_left_view.php')) {
$this->load->view('theme/'.$this->setting->get('config_template').'/template/common/column_left_view', $data);
} else {
$this->load->view('theme/default/template/common/column_left_view', $data);
}
}
}
View
<?php if ($modules) { ?>
<column id="column-left" class="col-sm-3 hidden-xs">
<?php foreach ($modules as $module) { ?>
<?php echo $module; ?>
<?php } ?>
</column>
<?php } ?>
After working on it all after noon, was able to find the cause of the issue.
In my catalog modules folder I had 2 controllers named the same in different folders, catalog/category & module/category. Even though they were in different folders one was over riding other and causing page load error on fire fox.
How I solved problem. By renaming the controller in subfolder catalog to categories I refreshed page and then works.
I also cleaned up code here.
<?php
class Column_left extends MX_Controller {
public function index() {
$this->load->model('catalog/design/model_design_layout');
$route = $this->uri->segment(1).'/'.$this->uri->segment(2);
$layout_id = 0;
if (!$layout_id) {
$layout_id = $this->model_design_layout->get_layout($route);
}
if (!$layout_id) {
$layout_id = $this->setting->get('config_layout_id');
}
$data['modules'] = array();
$results = $this->model_design_layout->get_layout_modules($layout_id);
foreach ($results as $result) {
$part = explode('.', $result['code']);
if (isset($part[0]) && $this->setting->get($part[0] . '_status')) {
$data['modules'][] = Modules::run('catalog/module/'.$part[0].'/index');
}
if (isset($part[1])) {
$this->load->model('catalog/extension/model_extension_module');
$setting_info = $this->model_extension_module->get_module($part[1]);
if ($setting_info && $setting_info['status']) {
$data['modules'][] = Modules::run('catalog/module/'.$part[0].'/index', $setting_info);
}
}
}
$this->load->view('theme/default/template/common/column_left_view', $data);
}
}
I try to parse a ini file to load PHP classes from it but whenever parse_ini_file parses the file, the variable that holds the content is always only "1".
Here is my code:
private $plugins = array();
public function __construct() {
Logger::log("Loading plugins");
Logger::debug("Loading " . APP_ROOT . DIRECTORY_SEPARATOR . "config" . DIRECTORY_SEPARATOR . "plugins.ini");
if (file_exists(APP_ROOT . DIRECTORY_SEPARATOR . "config" . DIRECTORY_SEPARATOR . "plugins.ini")) {
$data = parse_ini_file(APP_ROOT . DIRECTORY_SEPARATOR . "config" . DIRECTORY_SEPARATOR . "plugins.ini", true);
foreach ($data as $k => $d) {
if (class_exists($k)) {
$plugin = $this->createPlugin($k);
if ($plugin instanceof Plugin) {
$this->init($plugin, $d);
} else {
Logger::error("Plugin doesn't implements interface Plugin");
}
} else {
Logger::error("Can't load plugin $k");
}
}
} else {
Logger::error(APP_ROOT . DIRECTORY_SEPARATOR . "config" . DIRECTORY_SEPARATOR . "plugins.ini doesn't exists");
}
}
public function createPlugin($name) {
$plugin = unserialize(
sprintf(
'O:%d:"%s":0:{}', strlen($name), $name
)
);
return $plugin;
}
public function init(Plugin $plugin, $data) {
try {
Logger::log("Adding plugin " . get_class($plugin));
Logger::debug("Calling init");
$plugin->init($data);
$this->plugins[get_class($plugin)] = $plugin;
} catch (PluginException $ex) {
Logger::error("Error while init plugin");
}
}
The ini file:
[\eBot\Plugins\Official\MissionChecker]
url=http://someurl
I tried to add a log message after
foreach ($data as $k => $d) {
But this line was never called, therefore $data must be empty, buw how is that possible?
var_dump and print_r($data) show me "1".
I solved the problem by putting the url in the ini file in quotes.
[\eBot\Plugins\Official\MissionChecker]
url="http://someurl"
I am using codeigniter. I need to get all variables from a language file to an array.Is it possible?
Is there any method available like as follows?
$a = $this->load->language('editor');
print_r($a);
I was tried $this->lang->language; But,This will return labels from another language files loaded.
$CI = & get_instance();
$arr = $CI->lang->language;
Or Use following library
Class My_language {
var $language = array();
/**
* List of loaded language files
*
* #var array
*/
var $is_loaded = array();
function __construct() {
log_message('debug', "Language Class Initialized");
}
function load($langfile = '', $idiom = '', $return = FALSE, $add_suffix = TRUE, $alt_path = '') {
$langfile = str_replace('.php', '', $langfile);
if ($add_suffix == TRUE) {
$langfile = str_replace('_lang.', '', $langfile) . '_lang';
}
$langfile .= '.php';
if (in_array($langfile, $this->is_loaded, TRUE)) {
return;
}
$config = & get_config();
if ($idiom == '') {
$deft_lang = (!isset($config['language'])) ? 'english' : $config['language'];
$idiom = ($deft_lang == '') ? 'english' : $deft_lang;
}
// Determine where the language file is and load it
if ($alt_path != '' && file_exists($alt_path . 'language/' . $idiom . '/' . $langfile)) {
include($alt_path . 'language/' . $idiom . '/' . $langfile);
} else {
$found = FALSE;
foreach (get_instance()->load->get_package_paths(TRUE) as $package_path) {
if (file_exists($package_path . 'language/' . $idiom . '/' . $langfile)) {
include($package_path . 'language/' . $idiom . '/' . $langfile);
$found = TRUE;
break;
}
}
if ($found !== TRUE) {
show_error('Unable to load the requested language file: language/' . $idiom . '/' . $langfile);
}
}
if (!isset($lang)) {
log_message('error', 'Language file contains no data: language/' . $idiom . '/' . $langfile);
return;
}
if ($return == TRUE) {
return $lang;
}
$this->is_loaded[] = $langfile;
$this->language = array();
$this->language = $lang;
return $this->language;
unset($lang);
log_message('debug', 'Language file loaded: language/' . $idiom . '/' . $langfile);
return TRUE;
}
}
Call like this
$this->load->library('my_language');
$arr = $this->my_language->load('demo');
print_r($arr);
I know this is quite an old question, but I just want to give my solution for this problem since no answers has done the trick for this problem. (tested on codeigniter 3)
$this->load->helper('language');
$foo = $this->lang->load('lang_file', 'english', true);
print_r($foo);
notice that the third parameter for load method determines whether to return the loaded array of translations. source: codeigniter 3 docs.
hope this helps
Yeah ofcourse its possible. You can do like this :
//load helper for language
$this->load->helper('language');
//test is the language file in english folder
$this->lang->load('test','english');
//fetch all the data in $var variable
$var=$this->lang->language;
//print $var
print_r($var);
$var will return the array. :)
If you want to return language file data in Array than you need to pass the third parameter in load function.
$this->lang->load('header','hindi',true) // filename,language,true