Trying to modify a flash message function, but it is not working whatsoever. Is the $_SESSION[$type][$name] and so on format not acceptable?
function flash($type = '', $name = '', $message = '', $class = '', $dismiss = '' )
{
//We can only do something if name exists
if($name)
{
//No message, create it
if($message && empty($_SESSION[$type][$name]))
{
$_SESSION[$type][$name] = $message;
$_SESSION[$type][$name][$class] = $class;
$_SESSION[$type][$name][$dismiss] = $dismiss;
}
//Message exists, display it
else if($_SESSION[$type][$name] && empty($message))
{
echo '<div class="'.$_SESSION[$type][$name][$class].'">'.$_SESSION[$type][$name].' '.$_SESSION[$type][$name][$dismiss].'</div>';
unset($_SESSION[$type]);
}
}
}
Usage would be :
// set a message
<?php flash( 'error', 'test', 'whats up?', 'info', 'TRUE' ); ?>
// display a message
<?php flash( 'test' ); ?>
I think the problem you're having is you're overwriting the $message with an array here:
$_SESSION[$type][$name] = $message; // Sets the message
$_SESSION[$type][$name][$class] = $class; // Overwrites it with an array
All you'll need to do is save the message to the same array (and make sure the index you give it can never be the same as $class or $dismiss. So for example:
$_SESSION[$type][$name]['messagetext'] = $message;
Then, of course, update the display part of the code to use that index:
echo '<div class="'.$_SESSION[$type][$name][$class].'">'.$_SESSION[$type][$name]['messagetext'].' '.$_SESSION[$type][$name][$dismiss].'</div>';
EDIT: After the discussion in the comments, the final code could look like this provided there is only going to be one message per $type and $name combination:
function flash($type = '', $name = '', $message = '', $class = '', $dismiss = '' )
{
//We can only do something if name exists
if($type)
{
//No message, create it
if($message && empty($_SESSION[$type][$name]))
{
$_SESSION[$type][$name]['message'] = $message;
$_SESSION[$type][$name]['class'] = $class;
$_SESSION[$type][$name]['dismiss'] = $dismiss;
}
//Message exists, display it
else if($_SESSION[$type] && empty($message))
{
foreach($_SESSION[$type] as $name=>$array) {
echo '<div class="'.$_SESSION[$type][$name]['class'].'">'.$_SESSION[$type][$name]['message'].' '.$_SESSION[$type][$name]['dismiss'].'</div>';
}
unset($_SESSION[$type]);
}
}
}
Usage would be:
// set a message
<?php flash( 'error', 'test', 'whats up?', 'info', 'TRUE' ); ?>
// display all $type= 'error' messages
<?php flash( 'error' ); ?>
Related
I am experiencing some strange behavior when using json_encode.
This is my code:
if($_POST["action"] == 'profile')
{
sleep(2);
$error = '';
$success = '';
$admin_name = '';
$admin_contact_no = '';
$admin_email = '';
$admin_profile = '';
$data = array(
':admin_email' => $_POST["admin_email"],
':admin_id' => $_POST['hidden_id']
);
$visitor->query = "
SELECT * FROM admin_table
WHERE admin_email = :admin_email
AND admin_id != :admin_id
";
$visitor->execute($data);
if($visitor->row_count() > 0)
{
$error = '<div class="alert alert-danger">User Email Already Exists</div>';
}
else
{
$user_image = $_POST["hidden_user_image"];
if($_FILES["user_image"]["name"] != '')
{
$user_image = upload_image();
}
$admin_name = $visitor->clean_input($_POST["admin_name"]);
$admin_contact_no = $_POST["admin_contact_no"];
$admin_email = $_POST["admin_email"];
$admin_profile = $user_image;
$data = array(
':admin_name' => $admin_name,
':admin_contact_no' => $admin_contact_no,
':admin_email' => $admin_email,
':admin_profile' => $admin_profile
);
$visitor->query = "
UPDATE admin_table
SET admin_name = :admin_name,
admin_contact_no = :admin_contact_no,
admin_email = :admin_email,
admin_profile = :admin_profile
WHERE admin_id = '".$_POST['hidden_id']."'
";
$visitor->execute($data);
$success = '<div class="alert alert-success">User Details Updated</div>';
}
$output = array(
'error' => $error,
'success' => $success,
'admin_name' => $admin_name,
'admin_contact_no' => $admin_contact_no,
'admin_email' => $admin_email,
'admin_profile' => $admin_profile
);
echo json_encode($output);
}
Alert message for $error displays accordingly while alert message for $success does not.
If I swap positions between $error = '<div class="alert alert-danger">User Email Already Exists</div>'; and $success = '<div class="alert alert-success">User Details Updated</div>';, $error still works while $success still does not, which deeply confuses me.
I know I can avoid all this trouble by using echo, but I really want to find out what the issue is here.
Thank you for your help.
It was just a spelling error, wrote "succes" instead of "success".
I apologize for the trouble and thank you for your help.
Im trying to $_POST something if it's correctly filled in. At this point it inserts when it's good. But i need to check if it's correctly in before posting it. I've no clue how to do it.. Can you guys please give me a tip or tell me how to do it..
Thanks in advance.
if($_POST){
if( ! $sPageName = vad('pageName', $aPostClean)){
throw new Exception('Invalid page name');
}
if( ! $sPageUrl = name2title($sPageName)){
throw new Exception('Page name could not be made url safe');
}
if( ! $sParentPage = vad('parentId', $aPostClean)){
throw new Exception('Invalid parent page');
}
$aParentPage = explode(',', $sParentPage);
if(count($aParentPage) != 2){
throw new Exception('Invalid parent page');
}
$iParentId = $aParentPage[0];
if( ! $iParentId){
$sUrl = '/'.$sPageUrl.'/';
}else{
$sUrl = $aParentPage[1].$sPageUrl.'/';
}
if(vad('boolean_menu', $aPostClean) == 'true'){
$bMenu = true;
}
$aPageData = $oControllerWizard->addPage(
array(
'name' => str_replace('/', '_', $aPostClean['pageName']),
'url' => $sUrl,
'type' => $iSelectedId,
'in_menu' => $bMenu,
'locked' => false,
),
$iParentId
);
foreach($aPostClean as $k => $v){
if(strpos($k, 'eav_') === 0){
$sEavEntityName = str_replace('eav_', '', $k);
$aEavCol = vad($sEavEntityName, $aEavCols);
if( ! $aEavCol){
continue;
}
$sTypeClass = get_type_class(vad('type', $aEavCol));
if( ! $sTypeClass::validate($v, $oEavModel, $aEavCol)){
$this->removePage($aPageData['id']);
throw new Exception('Failed to validate eav column input');
}
$oControllerWizard->addEavValueByName($sEavEntityName, $aPageData['id'], $sTypeClass::save($v, $oEavModel, $aEavCol));
}
if(strpos($k, 'blocks_') === 0){
$sBlockName = str_replace('blocks_', '', $k);
$aBlockCol = vad($sBlockName, $aBlocksCols);
if( ! $aBlockCol){
continue;
}
$sTypeClass = get_type_class(vad('type', $aBlockCol));
if( ! $sTypeClass::validate($v, $oBlocksModel, $aBlockCol)){
$this->removePage($aPageData['id']);
throw new Exception('Failed to validate block column input');
}
$oControllerWizard->addBlockValueByName($sBlockName, $aPageData['id'], $aPageData['framework_view_id'], $sTypeClass::save($v, $oBlocksModel, $aBlockCol));
}
}
if($aPageData['framework_module_id']){
$oCmsModuleSettings = new framework\base_model('cms_module_settings');
$oCmsModuleSettings->setModuleIcon($aPostClean['input_moduleicon']);
$oCmsModuleSettings->setDisplayName($aPostClean['display_name']);
$oCmsModuleSettings->setModuleId($aPageData['framework_module_id']);
$oCmsModuleSettings->setFkWebsites($iWebsiteId);
$oCmsModuleSettings->save();
}
mess::col('Page has been added', true);
nav('/wizards/wizard/step-3/id:'.$iWebsiteId.'/');
}
How I normally do it:
<?php
if($_SERVER['REQUEST_METHOD'] == "POST") {
$error = 0; // start of script so error = 0
$errorMsg = Array(); // initiate error array
if(empty($_POST['name'])) { // name = empty
$error = 1; // set error to 1
$errorMsg[] = "Bla bla bla error message"; // add message to array
}
if(empty($_POST['name1'])) { // name1 = empty
$error = 1; // set error to 1
$errorMsg[] = "Bla bla bla error message1"; // add message to array
}
if(!($error)) {
// There is an error
foreach($errorMsg as $msg) {
echo $msg . "<br />";
/* If both name and name1 were empty, it would output:
Bla bla bla error message
Bla Bla Bla error message1
*/
}
} else {
// Everything was fine
echo "SUCCES"
}
}
I have this class for show error with session method using PHP.
class Messages {
//-----------------------------------------------------------------------------------------------
// Class Variables
//-----------------------------------------------------------------------------------------------
var $msgId;
var $msgTypes = array( 'help', 'info', 'warning', 'success', 'danger' );
var $msgClass = 'alert';
var $msgWrapper = " <div class='alert %s-%s flashit'>
<button class='close' aria-hidden='true' data-dismiss='alert' type='button'>×</button>
<p><i style='vertical-align: middle;' class='%s icon-2x'></i> %s</p>
</div>";
var $msgBefore = '';
var $msgAfter = "";
public function __construct() {
// Generate a unique ID for this user and session
$this->msgId = md5(uniqid());
// Create the session array if it doesnt already exist
if( !array_key_exists('flash_messages', $_SESSION) ) $_SESSION['flash_messages'] = array();
}
public function add($type, $message, $redirect_to=null) {
if( !isset($_SESSION['flash_messages']) ) return false;
if( !isset($type) || !isset($message[0]) ) return false;
// Replace any shorthand codes with their full version
if( strlen(trim($type)) == 1 ) {
$type = str_replace( array('h', 'i', 'w', 'e', 's'), array('help', 'info', 'warning', 'danger', 'success'), $type );
$icon = str_replace( array('h', 'i', 'w', 'e', 's'), array('fa-help', 'fa-info', 'fa-warning', 'fa-danger', 'fa-success'), $type );
// Backwards compatibility...
} elseif( $type == 'information' ) {
$type = 'info';
$icon = 'fa-info';
}
// Make sure it's a valid message type
if( !in_array($type, $this->msgTypes) ) die('"' . strip_tags($type) . '" is not a valid message type!' );
// If the session array doesn't exist, create it
if( !array_key_exists( $type, $_SESSION['flash_messages'] ) ) $_SESSION['flash_messages'][$type] = array();
$_SESSION['flash_messages'][$type][] = $message;
if( !is_null($redirect_to) ) {
header("Location: $redirect_to");
exit();
}
return true;
}
//-----------------------------------------------------------------------------------------------
// display()
// print queued messages to the screen
//-----------------------------------------------------------------------------------------------
public function display($type='all', $print=true) {
$messages = '';
$data = '';
if( !isset($_SESSION['flash_messages']) ) return false;
if( $type == 'g' || $type == 'growl' ) {
$this->displayGrowlMessages();
return true;
}
// Print a certain type of message?
if( in_array($type, $this->msgTypes) ) {
foreach( $_SESSION['flash_messages'][$type] as $msg ) {
$messages .= $this->msgBefore . $msg . $this->msgAfter;
}
$data .= sprintf($this->msgWrapper, $this->msgClass, $type,$icon,$messages);
// Clear the viewed messages
$this->clear($type);
// Print ALL queued messages
} elseif( $type == 'all' ) {
foreach( $_SESSION['flash_messages'] as $type => $msgArray ) {
$messages = '';
foreach( $msgArray as $msg ) {
$messages .= $this->msgBefore . $msg . $this->msgAfter;
}
$data .= sprintf($this->msgWrapper, $this->msgClass, $type,$icon,$messages);
}
// Clear ALL of the messages
$this->clear();
// Invalid Message Type?
} else {
return false;
}
// Print everything to the screen or return the data
if( $print ) {
echo $data;
} else {
return $data;
}
}
//..... more
}
Call:
$msg = new Messages();
$msg->add('i', 'This is a Information message!');
echo $msg->display();
Now in Output:
<i style="vertical-align: middle;" class=" icon-2x"></i>
Icon class not printed and empty: class=" icon-2x". how do can i fix this ?
EDit: Indeed i need to print for each type One class name.
I'm using Laravel 4 for a project, but got an issue. I'm not sure, what i'm doing wrong.
Details:
Form is posted to the controller's save function.
When validation fails, i'm redirecting to the create function
After redirect (using Redirect::to(somewhere)->withErrors($validator)->withInput()):
Validation errors are being displayed correctly (if any)
Input::old() is empty (it should contain previously submitted data)
Create function in controller
public function create()
{
$this->scripts[] = 'various js path here';
return View::make('admin.modules.events.create', array(
// Loading various scripts specified in this function
'scripts' => $this->scripts,
));
}
In the view:
...
{{ Form::bsInput('event_name', 'Event title', 'event title goes here', $error = (($errors->has('event_name')) ? $errors->get('event_name') : false), $type = 'text', Input::old('event_name')) }}
...
Note: bsInput is a wrapper around Form::Input() to create bootstrap controls together with labels
Controller:
public function save()
{
if (Input::has('submitEventSave'))
{
$event = Mihirevent::find(Input::get(event_id));
$event_add = false;
}
else
{
$event = new Mihirevent();
$event_add = true;
}
if ($event === false)
{
// doing something else
}
else
{
$event->event_name = Input::get('event_name');
$event->event_slug = Input::get('event_slug');
$event->event_description = Input::get('event_description');
$event->event_location_text = Input::get('event_location_text');
$event->event_location_data = Input::get('event_location_data');
$event->event_status = Input::get('event_status');
$event->featured_image = Input::get('featured_image');
$event->event_date_from = Input::get('event_date_from');
$event->event_date_until = Input::get('event_date_until');
$validation_rules = $event_add === true?$event->rules:$event->update_rules;
$inputs = array(
'event_name' => $event->event_name,
'event_slug' => $event->event_slug,
'event_location_text' => $event->event_location_text,
);
$validator = Validator::make($inputs, $validation_rules);
if ($validator->fails())
{
Input::flash();
if ($event_add === true)
{
return Redirect::to('admin/event/create')
->withErrors($validator)->withInput();
}
else
{
return Redirect::to('admin/event/edit/'.$event->event_id)
->withErrors($validator)->withInput();
}
}
// save
MihirEvent::save();
// redirect to list
return Redirect::route('adminEvent');
}
}
Update:
bsInput macro:
Form::macro('bsInput', function($name, $text, $placeholder = null, $error = false, $type = 'text', $default = null, $class=null)
{
$label = Form::label($name, $text, array('class' => 'control-label'));
$input = Form::input($type, $name, $default, array('placeholder' => $placeholder, 'class' => 'form-control'.($class?' '.$class:'')));
$error_messages = false;
if($error)
{
$error_messages = '<ol>';
foreach ($error as $value) {
$error_messages .= '<li>'.$value.'</li>';
}
$error_messages .= '</ol>';
}
$html = '<div class="form-group'.(($error) ? ' has-error' : '').'">';
$html .= $label;
$html .= $input;
$html .= (($error_messages) ? '<div class="alert alert-danger">'.$error_messages.'</div>' : '');
$html .= '</div>';
return $html;
});
Looking at the Laravel 4 source:
/**
* Flash an array of input to the session.
*
* #param array $input
* #return \Illuminate\Http\RedirectResponse
*/
public function withInput(array $input = null)
{
$input = $input ?: $this->request->input();
$this->session->flashInput($input);
return $this;
}
It looks like if you don't pass an array of Input with ->withInput it tries to pull it from the original request. Try modifying the line like so:
if ($event_add === true)
{
return Redirect::to('admin/event/create')
->withErrors($validator)->withInput(Input::all());
}
else
{
return Redirect::to('admin/event/edit/'.$event->event_id)
->withErrors($validator)->withInput(Input::all());
}
This should hopefully force it to pass the array of input values, instead of relying on the
'$this->request->input()'
still existing in the session.
You are doing Input::flash() and then withInput(), which effectively does Input::flash() twice, probably invalidating the flashed input. Try only doing one of the two.
Also, MihirEvent::save(); is wrong, you want to do $event->save();.
Finally i found the issue: There was a leading space in the routes.php file, before the <?php opening tag. (was working on a team and someone else added that space).
I am using a php session-based flash messenger available here. The issue is sometimes I get multiple messages of the same type when I generate errors, display messages, so on and so fourth. This is mostly due to some AJAX issues. Assuming that I wanted to only apply a fix in the display code here:
public function display($type = 'all', $print = true)
{
$messages = '';
$data = '';
if (!isset($_SESSION['flash_messages'])) {
return false;
}
// print a certain type of message?
if (in_array($type, $this->msgTypes)) {
foreach ($_SESSION['flash_messages'][$type] as $msg) {
$messages .= $this->msgBefore . $msg . $this->msgAfter;
}
$data .= sprintf($this->msgWrapper, $this->msgClass, $this->msgClassPrepend.'-'.$type, str_replace('messages', 'autoclose',$this->msgClassPrepend.'-'.$type), $messages);
// clear the viewed messages
$this->clear($type);
// print ALL queued messages
} elseif ($type == 'all') {
$counter = 1;
foreach ($_SESSION['flash_messages'] as $type => $msgArray) {
$count = $counter++;
$messages = '';
foreach ($msgArray as $msg) {
$messages .= $this->msgBefore . $msg . $this->msgAfter;
}
$data .= sprintf($this->msgWrapper, $this->msgClass, $this->msgClassPrepend.'-'.$type, str_replace('messages', 'autoclose', $this->msgClassPrepend.'-'.$type), $messages);
}
// clear ALL of the messages
$this->clear();
// invalid message type?
} else {
return false;
}
// print everything to the screen or return the data
if ($print) {
echo $data;
} else {
return $data;
}
}
How would I make it so that duplicate messages are detected on a 1 for 1 basis. So if the message is "Hello" and "Hello" and "Hello." I can remove one of the first two, and keep the later as it is a different message so to speak. All the workarounds I can think of would be overly complex, and I was wondering if anyone could think of a simple solution.
Additional info: display is encased in class Messages and a new message is created with
$msg = new Messages();
$msg->add('e', 'Some error here.');
You could simply run the message array through array_unique() before the $messages string is built. For example, these two additions to the display method should do the trick...
if (in_array($type, $this->msgTypes)) {
$filtered = array_unique($_SESSION['flash_messages'][$type]);
foreach ($filtered as $msg) {
and...
foreach ($_SESSION['flash_messages'] as $type => $msgArray) {
$count = $counter++;
$messages = '';
$filtered = array_unique($msgArray);
foreach ($filtered as $msg) {
Alternatively, you could override the add method with a unique check. For example
public function add($type, $message, $redirect_to = null, $ignoreDuplicates = true) {
// snip...
// wrap the array push in this check
if (!($ignoreDuplicates && in_array($message, $_SESSION['flash_messages'][$type]))) {
$_SESSION['flash_messages'][$type][] = $message; // this is the existing code
}
// snip...
}