php array page system, not working - php

So I'm working on setting up my first "fancy" page system, and I have run into a problem. I use the code seen below, and it loads the "profile" page without any problems, and the default page works fine too. However the other two pages does not show at all, and I can't seem to request them in the URL eighter. All the files are there tho. Any help here will be much appreciated! :)
if(isset($_SESSION['user_id'])){
require('user.php');
$player = new user($_SESSION['user_id'], $database);
$default_page = 'profile';
$pages = array(
'profile' => array(
'name' => 'Profile',
'file' => 'profile.php',
'function' => 'profile',
),
'create_monster' => array(
'name' => 'Create Monster',
'file' => 'monsterPages.php',
'function' => 'createMonster',
),
'create_attack' => array(
'name' => 'Create Attack',
'file' => 'attackPages.php',
'function' => 'createAttack',
),
);
if(!empty($_GET['page'])){
$page = strtolower(trim($_GET['page']));
if(isset($pages[$page])){
require($pages[$page]['file']);
echo "<p class='pageTitle'>" . $pages[$page]['name'] . "</p>";
$pages[$page]['function']();
}
else{
require($pages[$default_page]['file']);
echo "<p class='pageTitle'>" . $pages[$default_page]['name'] . "</p>";
$pages[$default_page]['function']();
}
}
else{
require($pages[$default_page]['file']);
echo "<p class='pageTitle'>" . $pages[$default_page]['name'] . "</p>";
$pages[$default_page]['function']();
}
}

You've got some redundancy in your code. You could abbreviate it.
$page = isset($_GET['page']) ? $_GET['page'] : $default_page;
// You should check that the page exists here.
require($pages[$page]['file']);
echo "<p class='pageTitle'>" . $pages[$page]['name'] . "</p>";
$pages[$page]['function']();
I suggest you place the page loading code in a function. I've created a simple class here:
<?php
$pages = array(
'profile' => array(
'name' => 'Profile',
'file' => 'profile.php',
'function' => 'profile',
),
'create_monster' => array(
'name' => 'Create Monster',
'file' => 'monsterPages.php',
'function' => 'createMonster',
),
'create_attack' => array(
'name' => 'Create Attack',
'file' => 'attackPages.php',
'function' => 'createAttack',
),
);
class PageLoader
{
public $pages;
public $base_path;
public function __construct($pages, $base_path)
{
$this->pages = $pages;
$this->base_path = $base_path;
}
public function run($name) {
if(! isset($this->pages[$name])) {
throw new Exception('Page not found');
}
$path = $this->base_path . DIRECTORY_SEPARATOR . $this->pages[$name]['file'];
$func = $this->pages[$name]['function'];
require_once $path;
call_user_func($func);
}
}
$page = isset($_GET['page']) ? $_GET['page'] : 'profile'; // If no page given default to profile.
$loader = new PageLoader($pages, '/tmp');
$loader->run($page);

Before you can use $_SESSION, you need to start the session:
session_start(); # this should be the very 1st line in your php
if(isset($_SESSION['user_id'])){
// ...
}
else{
require($pages[$default_page]['file']);
echo "<p class='pageTitle'>" . $pages[$default_page]['name'] . "</p>";
$pages[$default_page]['function']();
}
}
and make sure that $pages[$default_page]['function'](); sets $_SESSION['user_id']

Related

What is the best way to edit a settings file containing a global named config in php

I've got the file 'init.php'. This one is being used to start the session, set some settings and that sort of stuff. I call to this file using this line:
require_once 'core/init.php';
This works perfectly in my opinion. Now, I've written the following script so that it becomes very easy to call a setting in the init.php file.
class Config {
public static function get($path = null) {
if ($path){
$config = $GLOBALS['config'];
$path = explode('/', $path);
foreach($path as $bit) {
if(isset($config[$bit])) {
$config = $config[$bit];
}
}
return $config;
}
return false;
}
}
So now I can use this line of code in my other pages to use the setting:
Config::get('settings/main_color')
This is very easy of course. But now I'd like to edit a setting without having to change the file myself. It should all be done by scripts in the browser. The rest of my init.php settings global looks like this:
$GLOBALS['config'] = array(
'mysql' => array(
'host' => 'localhost:3307',
'username' => 'root',
'password' => 'usbw',
'db' => 'webshop'
),
'remember' => array(
'cookie_name' => 'hash',
'cookie_expiry' => 604800
),
'sessions' => array(
'session_name' => 'user',
'token_name' => 'token'
),
'settings' => array(
'main_color' => '#069CDE',
'front_page_cat' => 'Best Verkocht,Populaire Producten',
'title_block_first' => 'GRATIS verzending van €50,-',
'title_block_second' => 'Vandaag besteld morgen in huis!',
),
'statics' => array(
'header' => 'enabled',
'title_block' => 'enabled',
'menu' => 'enabled',
'slideshow' => 'enabled',
'left_box' => 'enabled',
'email_block' => 'enabled',
'footer' => 'enabled',
'keurmerken' => 'enabled',
'copyright' => 'enabled'
)
);
What I hope for is a solution like this:
Config::update('settings/main_color','blue')
What is the best way to achieve this? Use str_replace and replace the word in the file? I hope there's a better way of doing this, and I'd be very pleased if you could help me out.
EDIT: (my complete init.php file)
<?php
session_start();
define('DS',DIRECTORY_SEPARATOR);
$GLOBALS['config'] = json_decode(__DIR__.DS.'prefs.json', true);
spl_autoload_register(function($class) {
require_once 'classes/' . $class . '.php';
});
require_once 'functions/sanitize.php';
require_once 'functions/statics.php';
require_once 'functions/pagination.php';
if(Cookie::exists(Config::get('remember/cookie_name')) && !Session::exists(Config::get('sessions/session_name'))) {
$hash = Cookie::get(Config::get('remember/cookie_name'));
$hashCheck = DB::getInstance()->get('users_session', array('hash', '=', $hash));
if($hashCheck->count()) {
$user = new User($hashCheck->first()->user_id);
$user->login();
}
}
$_link = DB::getConnected();
$url_parts = explode('/',$_SERVER['REQUEST_URI']);
$current = $url_parts[count($url_parts)-2];
if($current == 'page'){
$_SESSION['location'] = 1;
}
else{
$_SESSION['location'] = 0;
}
This is somewhat opinion-based, but I use a json or xml file that the config file parses. The update would call the file, parse it then resave it.
/core/init.php
$GLOBALS['config'] = json_decode(__DIR__.DS.'prefs.json', true);
/core/prefs.json
{"mysql":{"host":"localhost:3307","username":"root","password":"usbw","db":"webshop"},"remember":{"cookie_name":"hash","cookie_expiry":604800},"sessions":{"session_name":"user","token_name":"token"},"settings":{"main_color":"#069CDE","front_page_cat":"Best Verkocht,Populaire Producten","title_block_first":"GRATIS verzending van €50,-","title_block_second":"Vandaag besteld morgen in huis!"},"statics":{"header":"enabled","title_block":"enabled","menu":"enabled","slideshow":"enabled","left_box":"enabled","email_block":"enabled","footer":"enabled","keurmerken":"enabled","copyright":"enabled"}}
Pseudo-code for your update:
class Config
{
public static function update($path,$value)
{
# Fetch the file and convert it to json
$file = json_decode(file_get_contents(CONFIG_PATH),true);
# Do some code that will update the value....
# Save file back
file_put_contents(CONFIG_PATH,json_encode($data));
# Call your prefs to GLOBALS function here so the settings
# are updated in your global array
}
}

Campaign Monitor php sdk - add Subscribe bug - no longer showing on list

I am working on a campaign monitor api which creates a custom list with custom fields.
When I try and add subscribers it used to work, now when I look at the list its not added them. Although its still returning a success code 201.
function addSubscriber($list_id, $emailAddress, $name, $title, $showName, $showDate, $showTime){
//create subscriber
$subscriber = array(
'EmailAddress' => $emailAddress,
'Name' => $name,
'CustomFields' => array(
array(
'Key' => "Title",
'Value' => $title
),
array(
'Key' => "ShowName",
'Value' => $showName
),
array(
'Key' => "ShowDate",
'Value' => $showDate
),
array(
'Key' => "ShowTime",
'Value' => $showTime
)
),
'Resubscribe' => true,
'RestartSubscriptionBasedAutoResponders' => true
);
//print_r($subscriber);
$subwrap = new CS_REST_Subscribers($list_id, $this->auth);
$result = $subwrap->add($subscriber);
//var_dump($result->response);
echo "Result of POST /api/v3.1/subscribers/{list id}.{format}\n<br />";
if($result->was_successful()) {
echo "Subscribed with code ".$result->http_status_code;
} else {
echo 'Failed with code '.$result->http_status_code."\n<br /><pre>";
var_dump($result->response);
echo '</pre>';
}
return $result->response;
}
This code is working for me.You need to add campaign monitor class files in you project folder and use valid list id and api key.You can find you api key from manage account link and list id from click on (change name/type) below list title. Please wait some time to see in you list.
require_once 'csrest_subscribers.php';
$name=$_POST['name'];
$email=$_POST['email'];
$wrap = new CS_REST_Subscribers('Your list ID', 'Your API Key');
$result = $wrap->add(array(
'EmailAddress' => $email,
'Name' => $name,
'CustomFields' => array(), // no custom fields, can remove this line completely
'Resubscribe' => true
));
echo "Result of POST /api/v3/subscribers/{list id}.{format}\n<br />";
if($result->was_successful()) {
echo "Subscribed with code ".$result->http_status_code;
} else {
echo 'Failed with code '.$result->http_status_code."\n<br /><pre>";
var_dump($result->response);
echo '</pre>';
}

Codeigniter Custom data validation

I will try to upload an Excel file and verify its contents.
So I tried the code as below.
if ($this->upload->do_upload("filename"))
{
...
// I Think it is idiot code . . but . . anyway . . :_(
$_POST = array(
"name" => $cell[0],
"phone" => $cell[1],
"birth" => $cell[2],
...
);
$config = array(
array("field"=>"name", "label"=>"Name", "rule"=> "required"),
...
);
$this->form_validation->set_rules($config);
$this->form_validation->set_error_delimiters('', '');
if ($this->form_validation->run() === false)
{
throw new Exception($this->form_validation->error_string());
}
...
}
How to validate custom data using form_validation?
You can pass your data like that:
$data = array(
'username' => 'johndoe',
'password' => 'mypassword',
'passconf' => 'mypassword'
);
$this->form_validation->set_data($data);

zf2 how to upload files, more than 1 file

I refer to http://samsonasik.wordpress.com/2012/08/31/zend-framework-2-creating-upload-form-file-validation/ and follow this, I can upload 1 file successfully by using rename filter in ZF2.
However when I use this way to upload 2 files, it goes wrong. I paste my code as following:
$this->add(array(
'name' => 'bigpicture',
'attributes' => array(
'type' => 'file'
),
'options' => array(
'label' => 'Big Pic'
)
));
$this->add(array(
'name' => 'smallpicture',
'attributes' => array(
'type' => 'file'
),
'options' => array(
'label' => 'Small Pic'
)
));
<div class="row"><?php echo $this->formRow($form->get('smallpicture')) ?></div>
<div class="row"><?php echo $this->formRow($form->get('bigpicture')) ?></div>
$data = array_merge(
$request->getPost()->toArray(),
$request->getFiles()->toArray()
);
$form->setData($data);
if ($form->isValid()) {
$product->exchangeArray($form->getData());
$picid = $this->getProductTable()->saveProduct($product);
$pathstr = $this->md5path($picid);
$this->folder('public/images/product/'.$pathstr);
//move_uploaded_file($data['smallpicture']['tmp_name'], 'public/images/product/'.$pathstr.'/'.$picid.'_small.jpg');
//move_uploaded_file($data['bigpicture']['tmp_name'], 'public/images/product/'.$pathstr.'/'.$picid.'_big.jpg');
$fileadaptersmall = new \Zend\File\Transfer\Adapter\Http();
$fileadaptersmall->addFilter('File\Rename',array(
'source' => $data['smallpicture']['tmp_name'],
'target' => 'public/images/product/'.$pathstr.'/'.$picid.'_small.jpg',
'overwrite' => true
));
$fileadaptersmall->receive();
$fileadapterbig = new \Zend\File\Transfer\Adapter\Http();
$fileadapterbig->addFilter('File\Rename',array(
'source' => $data['bigpicture']['tmp_name'],
'target' => 'public/images/product/'.$pathstr.'/'.$picid.'_big.jpg',
'overwrite' => true
));
$fileadapterbig->receive();
}
the above are form,view,action.
using this way, only the small picture uploaed successfully. the big picture goes wrong.
a warning flashed like the following:
Warning:move_uploaded_file(C:\WINDOWS\TMP\small.jpg):failed to open stream:Invalid argument in
E:\myproject\vendor\zendframework\zendframework\library\zend\file\transfer\adapter\http.php
on line 173
Warning:move_uploaded_file():Unable to move 'C:\WINDOWS\TMP\php76.tmp'
to 'C:\WINDOWS\TEMP\big.jpg' in
E:\myproject\vendor\zendframework\zendframework\library\zend\file\transfer\adapter\http.php
on line 173
Who can tell me how to upload more than 1 file in this way. you know, the rename filter way similar to above. thanks.
I ran into the same problem with a site i did. The solution was to do the renaming in the controller itself by getting all the images and then stepping through them.
if ($file->isUploaded()) {
$pInfo = pathinfo($file->getFileName());
$time = uniqid();
$newName = $pName . '-' . $type . '-' . $time . '.' . $pInfo['extension'];
$file->addFilter('Rename', array('target' => $newName));
$file->receive();
}
Hope this helps point you in the right direction.
I encountered the same problem and i managed to make it work using the below code;
$folder = 'YOUR DIR';
$adapter = new \Zend\File\Transfer\Adapter\Http();
$adapter->setDestination($folder);
foreach ($adapter->getFileInfo() as $info) {
$originalFileName = $info['name'];
if ($adapter->receive($originalFileName)) {
$newFilePath = $folder . '/' . $newFileName;
$adapter->addFilter('Rename', array('target' => $newFilePath,
'overwrite' => true));
}
}

Can this PHP function be improved?

Below is some code I am working on for a navigation menu, if you are on a certain page, it will add a "current" css class to the proper tab.
I am curious if there is a better way to do this in PHP because it really seems like a lot of code to do such a simple task? My pages will also have a jquery library already loaded, would it be better to set the tab with jquery instead of PHP? Any tips appreciated
<?PHP
active_header('page identifier goes here'); //ie; 'home' or 'users.online'
function active_header($page_name)
{
// arrays for header menu selector
$header_home = array('home' => true);
$header_users = array(
'users.online' => true,
'users.online.male' => true,
'users.online.female' => true,
'users.online.friends' => true,
'users.location' => true,
'users.featured' => true,
'users.new' => true,
'users.browse' => true,
'users.search' => true,
'users.staff' => true
);
$header_forum = array('forum' => true);
$header_more = array(
'widgets' => true,
'news' => true,
'promote' => true,
'development' => true,
'bookmarks' => true,
'about' => true
);
$header_money = array(
'account.money' => true,
'account.store' => true,
'account.lottery' => true,
'users.top.money' => true
);
$header_account = array('account' => true);
$header_mail = array(
'mail.inbox' => true,
'mail.sentbox' => true,
'mail.trash' => true,
'bulletins.post' => true,
'bulletins.my' => true,
'bulletins' => true
);
// set variables if there array value exist
if (isset($header_home[$page_name])){
$current_home = 'current';
}else if (isset($header_users[$page_name])){
$current_users = 'current';
}else if (isset($header_forum[$page_name])){
$current_forum = 'current';
}else if (isset($header_more[$page_name])){
$current_more = 'current';
}else if (isset($header_money[$page_name])){
$current_money = 'current';
}else if (isset($header_account[$page_name])){
$current_account = 'current';
}else if (isset($header_mail[$page_name])){
$current_mail = 'current';
}
// show the links
echo '<li class="' . (isset($current_home) ? $current_home : '') . '"><em>Home</em></li>';
echo '<li class="' . (isset($current_users) ? $current_users : '') . '"><em>Users</em></li>';
echo '<li class="' . (isset($current_forum) ? $current_forum : '') . '"><em>Forum</em></li>';
echo '<li class="' . (isset($current_more) ? $current_more : '') . '"><em>More</em></li>';
echo '<li class="' . (isset($current_money) ? $current_money : '') . '"><em>Money</em></li>';
echo '<li class="' . (isset($current_account) ? $current_account : '') . '"><em>Account</em></li>';
echo '<li class="' . (isset($current_mail) ? $current_mail : '') . '"><em>Mail</em></li>';
}
?>
The two very large blocks of code at the bottom could be reduced drastically to a simple loop:
<?php
foreach (array('home', 'users', 'forum' /* ... */ ) as $item) {
$ar = "header_$item";
echo '<li class="', (isset($$ar[$page_name]) ? 'current' : '')
, '"><em>', ucword($item), '</em></li>';
}
?>
You should try not to print <li class=""> or something like that; it looks messy. I've moved the checking of whether this page or not is the one to highlight to a seperate function in case you end up changing the layout of $applicable_list.
<?php
function active_header($page) {
$applicable_list = array(
"home" => array("home"),
"users" => array(
"users.online", "users.online.male", "users.online.female", "users.online.friends",
"users.location", "users.featured", "users.new", "users.browse", "users.search", "users.staff"
),
"forum" => array("forum"),
"more" => array("widgets", "news", "promote", "development", "bookmarks", "about"),
"money" => array("account.money", "account.store", "account.lottery", "users.top.money"),
"account" => array("account"),
"mail" => array("mail.inbox", "mail.sentbox", "mail.trash", "bulletins.post", "bulletins.my", "bulletins")
);
$pages = array_keys($applicable_list);
function is_active_page($page, $category, $category_pages_list) {
return array_key_exists($category, $category_pages_list) && in_array($page, $category_pages_list[$category]);
}
foreach($pages as $key => $category) {
printf('<li%s><em>%s</em></li>' . "\n",
(is_active_page($page, $category, $applicable_list) ? ' class="current"' : ''),
ucwords($category)
);
}
}
?>
May as well throw in my lot. Output is restricted to match that given in the original question.
<?PHP
active_header('page identifier goes here'); //ie; 'home' or 'users.online'
function active_header($page_name)
{
// Unified array
$headers = array(
'Home' => array('home' => true),
'Users' => array(
'users.online' => true,
'users.online.male' => true,
'users.online.female' => true,
'users.online.friends' => true,
'users.location' => true,
'users.featured' => true,
'users.new' => true,
'users.browse' => true,
'users.search' => true,
'users.staff' => true
),
'Forum' => array('forum' => true),
'More' => array(
'widgets' => true,
'news' => true,
'promote' => true,
'development' => true,
'bookmarks' => true,
'about' => true
),
'Money' => array(
'account.money' => true,
'account.store' => true,
'account.lottery' => true,
'users.top.money' => true
),
'Account' => array('account' => true),
'Mail' => array(
'mail.inbox' => true,
'mail.sentbox' => true,
'mail.trash' => true,
'bulletins.post' => true,
'bulletins.my' => true,
'bulletins' => true
)
);
foreach($headers as $header => &$pages) {
echo '<li class="';
if(isset($pages[$page_name])) echo 'content';
echo '"><em>', $header, '</em></li>';
}
}
?>
I'm not a fan of mixing up the code with the output, but it'll do for example.
PHP hint of the day: Don't use string concatenation if you're just echoing a string
Rather than using the page names as array keys you could simply have arrays of the page names, and then compare using in_array($page_name, $array), rather than isset($array[$page_name]).
This should happily work alongside the alterations from #meager, and would allow the static bits of code at the top to shrink a little.
Consolidate your arrays, or put all that logic in another well-named function. My example consolidates the arrays.
// it's ugly, but at least the ugliness
// is confined to only _one_ array ;)
$map_pages_to_navitem = array(
'home' => 'home',
'users.online' => 'users',
'users.online.male' => 'users',
'users.online.female' => 'users',
'users.online.friends' => 'users',
'users.location' => 'users',
'users.featured' => 'users',
'users.new' => 'users',
'users.browse' => 'users',
'users.search' => 'users',
'users.staff' => 'users',
'forum' => 'forum',
'widgets' => 'more',
'news' => 'more',
'promote' => 'more',
'development' => 'more',
'bookmarks' => 'more',
'about' => 'more',
'account.money' => 'money',
'account.store' => 'money',
'account.lottery' => 'money',
'users.top.money' => 'money',
'account' => 'account'),
'mail.inbox' => 'mail',
'mail.sentbox' => 'mail',
'mail.trash' => 'mail',
'bulletins.post' => 'mail',
'bulletins.my' => 'mail',
'bulletins' => 'mail',
);
$current = $map_pages_to_navitem[$page_name];
echo '<li class="'.($current=='home')?'current':''.'"><em>Home</em></li>';
echo '<li class="'.($current=='users')?'current':''.'"><em>Users</em></li>';
echo '<li class="'.($current=='forum')?'current':''.'"><em>Forum</em></li>';
echo '<li class="'.($current=='more')?'current':''.'"><em>More</em></li>';
echo '<li class="'.($current=='money')?'current':''.'"><em>Money</em></li>';
echo '<li class="'.($current=='account')?'current':''.'"><em>Account</em></li>';
echo '<li class="'.($current=='mail')?'current':''.'"><em>Mail</em></li>';
Looking at the code, I also see the end result is to assign on <li> element a class attribute value. JavaScript will do this better than PHP.
So you could give each <li> an id and leave the assignment of the class attribute to JavaScript:
echo '<li id="home"><em>Home</em></li>';
echo '<li id="users"><em>Users</em></li>';
echo '<li id="forum"><em>Forum</em></li>';
echo '<li id="more"><em>More</em></li>';
echo '<li id="money"><em>Money</em></li>';
echo '<li id="account"><em>Account</em></li>';
echo '<li id="mail"><em>Mail</em></li>';
echo '<script type="text/javascript">';
echo 'document.getElementById("'.$current.'").className = "current";';
// you'll want to sanitize $current to avoid parse errors in your JS
echo '</script>'
Use a switch instead of extensive if/else for starters :-)
// set variables if there array value exist
if (isset($header_home[$page_name])){
$current_home = 'current';
}else if (isset($header_users[$page_name])){
$current_users = 'current';
}else if (isset($header_forum[$page_name])){
$current_forum = 'current';
}else if (isset($header_more[$page_name])){
$current_more = 'current';
}else if (isset($header_money[$page_name])){
$current_money = 'current';
}else if (isset($header_account[$page_name])){
$current_account = 'current';
}else if (isset($header_mail[$page_name])){
$current_mail = 'current';
}
You can use variables variable ( http://www.php.net/manual/en/language.variables.variable.php ), foreach and break to reduce this part of function
I don't see any compelling reason to change your original code. It's very easy to read and understand, and easy enough to modify. I also don't think there's any reason to use Javascript to set the tab indicator. By using PHP, you cater to people who have javascript disabled, and I like to save Javascript for when it's truly needed.
If not changing to "return htmlcode" from "printing htmlcode", i would at least add a second parameter for that.

Categories