How to get data attribute for div item on another page - php

I am using slim image cropper.
I have the following.
<div class="slim" data-service="async.php" data-ratio="3:2" data-size="600,400" data-row="">
<!-- <input type="hidden" id="rowID" name="rowID"> -->
<input type="file"/>
</div>
I added the data-row=" " and then in the jQuery I added the following.
$('.slim').attr('data-row', rowID);
That part is working fine, but now how do I retrieve the value of the data-row on the async.php page?
Here is ASYNC.php
<?php
// Uncomment if you want to allow posts from other domains
// header('Access-Control-Allow-Origin: *');
require_once('slim.php');
foreach(Slim::getImages() as $imagess) {
echo $imagess['meta']->data-row;
}
// Get posted data, if something is wrong, exit
try {
$images = Slim::getImages();
}
catch (Exception $e) {
// Possible solutions
// ----------
// Make sure you're running PHP version 5.6 or higher
Slim::outputJSON(array(
'status' => SlimStatus::FAILURE,
'message' => 'Unknown'
));
return;
}
// No image found under the supplied input name
if ($images === false) {
// Possible solutions
// ----------
// Make sure the name of the file input is "slim[]" or you have passed your custom
// name to the getImages method above like this -> Slim::getImages("myFieldName")
Slim::outputJSON(array(
'status' => SlimStatus::FAILURE,
'message' => 'No data posted'
));
return;
}
// Should always be one image (when posting async), so we'll use the first on in the array (if available)
$image = array_shift($images);
// Something was posted but no images were found
if (!isset($image)) {
// Possible solutions
// ----------
// Make sure you're running PHP version 5.6 or higher
Slim::outputJSON(array(
'status' => SlimStatus::FAILURE,
'message' => 'No images found'
));
return;
}
// If image found but no output or input data present
if (!isset($image['output']['data']) && !isset($image['input']['data'])) {
// Possible solutions
// ----------
// If you've set the data-post attribute make sure it contains the "output" value -> data-post="actions,output"
// If you want to use the input data and have set the data-post attribute to include "input", replace the 'output' String above with 'input'
Slim::outputJSON(array(
'status' => SlimStatus::FAILURE,
'message' => 'No image data'
));
return;
}
// if we've received output data save as file
if (isset($image['output']['data'])) {
// get the name of the file
$name = $image['output']['name'];
// get the crop data for the output image
$data = $image['output']['data'];
// If you want to store the file in another directory pass the directory name as the third parameter.
// $output = Slim::saveFile($data, $name, 'my-directory/');
// If you want to prevent Slim from adding a unique id to the file name add false as the fourth parameter.
// $output = Slim::saveFile($data, $name, 'tmp/', false);
// Default call for saving the output data
$output = Slim::saveFile($data, $name, 'images/modules/listings');
}
// if we've received input data (do the same as above but for input data)
if (isset($image['input']['data'])) {
// get the name of the file
$name = $image['input']['name'];
// get the crop data for the output image
$data = $image['input']['data'];
// If you want to store the file in another directory pass the directory name as the third parameter.
// $input = Slim::saveFile($data, $name, 'my-directory/');
// If you want to prevent Slim from adding a unique id to the file name add false as the fourth parameter.
// $input = Slim::saveFile($data, $name, 'tmp/', false);
// Default call for saving the input data
$input = Slim::saveFile($data, $name, 'images/modules/listings');
}
//
// Build response to client
//
$response = array(
'status' => SlimStatus::SUCCESS
);
if (isset($output) && isset($input)) {
$response['output'] = array(
'file' => $output['name'],
'path' => $output['path']
);
$response['input'] = array(
'file' => $input['name'],
'path' => $input['path']
);
}
else {
$response['file'] = isset($output) ? $output['name'] : $input['name'];
$response['path'] = isset($output) ? $output['path'] : $input['path'];
}
// Return results as JSON String
Slim::outputJSON($response);
Here is the SLIM.php
<?php
abstract class SlimStatus {
const FAILURE = 'failure';
const SUCCESS = 'success';
}
class Slim {
public static function getImages($inputName = 'slim') {
$values = Slim::getPostData($inputName);
// test for errors
if ($values === false) {
return false;
}
// determine if contains multiple input values, if is singular, put in array
$data = array();
if (!is_array($values)) {
$values = array($values);
}
// handle all posted fields
foreach ($values as $value) {
$inputValue = Slim::parseInput($value);
if ($inputValue) {
array_push($data, $inputValue);
}
}
// return the data collected from the fields
return $data;
}
// $value should be in JSON format
private static function parseInput($value) {
// if no json received, exit, don't handle empty input values.
if (empty($value)) {return null;}
// If magic quotes enabled
if (get_magic_quotes_gpc()) {
$value = stripslashes($value);
}
// The data is posted as a JSON String so to be used it needs to be deserialized first
$data = json_decode($value);
// shortcut
$input = null;
$actions = null;
$output = null;
$meta = null;
if (isset ($data->input)) {
$inputData = null;
if (isset($data->input->image)) {
$inputData = Slim::getBase64Data($data->input->image);
}
else if (isset($data->input->field)) {
$filename = $_FILES[$data->input->field]['tmp_name'];
if ($filename) {
$inputData = file_get_contents($filename);
}
}
$input = array(
'data' => $inputData,
'name' => $data->input->name,
'type' => $data->input->type,
'size' => $data->input->size,
'width' => $data->input->width,
'height' => $data->input->height,
);
}
if (isset($data->output)) {
$outputDate = null;
if (isset($data->output->image)) {
$outputData = Slim::getBase64Data($data->output->image);
}
else if (isset ($data->output->field)) {
$filename = $_FILES[$data->output->field]['tmp_name'];
if ($filename) {
$outputData = file_get_contents($filename);
}
}
$output = array(
'data' => $outputData,
'name' => $data->output->name,
'type' => $data->output->type,
'width' => $data->output->width,
'height' => $data->output->height
);
}
if (isset($data->actions)) {
$actions = array(
'crop' => $data->actions->crop ? array(
'x' => $data->actions->crop->x,
'y' => $data->actions->crop->y,
'width' => $data->actions->crop->width,
'height' => $data->actions->crop->height,
'type' => $data->actions->crop->type
) : null,
'size' => $data->actions->size ? array(
'width' => $data->actions->size->width,
'height' => $data->actions->size->height
) : null,
'rotation' => $data->actions->rotation,
'filters' => $data->actions->filters ? array(
'sharpen' => $data->actions->filters->sharpen
) : null
);
}
if (isset($data->meta)) {
$meta = $data->meta;
}
// We've sanitized the base64data and will now return the clean file object
return array(
'input' => $input,
'output' => $output,
'actions' => $actions,
'meta' => $meta
);
}
// $path should have trailing slash
public static function saveFile($data, $name, $path = 'tmp/', $uid = true) {
// Add trailing slash if omitted
if (substr($path, -1) !== '/') {
$path .= '/';
}
// Test if directory already exists
if(!is_dir($path)){
mkdir($path, 0755, true);
}
// Sanitize characters in file name
$name = Slim::sanitizeFileName($name);
// Let's put a unique id in front of the filename so we don't accidentally overwrite other files
if ($uid) {
$name = uniqid() . '_' . $name;
}
// Add name to path, we need the full path including the name to save the file
$path = $path . $name;
// store the file
Slim::save($data, $path);
// return the files new name and location
return array(
'name' => $name,
'path' => $path
);
}
/**
* Get data from remote URL
* #param $url
* #return string
*/
public static function fetchURL($url, $maxFileSize) {
if (!ini_get('allow_url_fopen')) {
return null;
}
$content = null;
try {
$content = #file_get_contents($url, false, null, 0, $maxFileSize);
} catch(Exception $e) {
return false;
}
return $content;
}
public static function outputJSON($data) {
header('Content-Type: application/json');
echo json_encode($data);
}
/**
* http://stackoverflow.com/a/2021729
* Remove anything which isn't a word, whitespace, number
* or any of the following characters -_~,;[]().
* If you don't need to handle multi-byte characters
* you can use preg_replace rather than mb_ereg_replace
* #param $str
* #return string
*/
public static function sanitizeFileName($str) {
// Basic clean up
$str = preg_replace('([^\w\s\d\-_~,;\[\]\(\).])', '', $str);
// Remove any runs of periods
$str = preg_replace('([\.]{2,})', '', $str);
return $str;
}
/**
* Gets the posted data from the POST or FILES object. If was using Slim to upload it will be in POST (as posted with hidden field) if not enhanced with Slim it'll be in FILES.
* #param $inputName
* #return array|bool
*/
private static function getPostData($inputName) {
$values = array();
if (isset($_POST[$inputName])) {
$values = $_POST[$inputName];
}
else if (isset($_FILES[$inputName])) {
// Slim was not used to upload this file
return false;
}
return $values;
}
/**
* Saves the data to a given location
* #param $data
* #param $path
* #return bool
*/
private static function save($data, $path) {
if (!file_put_contents($path, $data)) {
return false;
}
return true;
}
/**
* Strips the "data:image..." part of the base64 data string so PHP can save the string as a file
* #param $data
* #return string
*/
private static function getBase64Data($data) {
return base64_decode(preg_replace('#^data:image/\w+;base64,#i', '', $data));
}
}
That is all the pages includes, I am not sure where to even add this so I can retrieve this rowID, is it under the async, or the slim. Sorry for the confusion. Hopefully adding these pages helped clear some stuff up.

Your HTML can stay the same.
<div class="slim" data-service="async.php" data-ratio="3:2" data-size="600,400">
<input type="file" />
</div>
Append data-meta-data-row to contain the rowID as well in your JS.
(['data-meta-data-row', 'data-row']).forEach( (key) => {
$('.slim').attr(key, rowID);
});
On the server side, you can then use the meta key which holds an object of properties like so:
foreach(Slim::getImages() as $image)
echo $image['meta']->data-row;

So after lots of hacking. I figured it out with the help of the slim frameworks developer.
Per the documentation, there is a function called willSave, this can be triggered and will update whenever is called on the server.
The meta data for slim is only called on page load, that is why it was never reading when the variable was updated via my custom function.
My fix was the following:
After opening the modal, I created the will save function. I passed the variable from the function that opens the modal, to the save function.
Code below for reference and big shout out to the developer for the initial help.
html
<div id="slim" class="slim" data-service="async.php" data-ratio="3:2" data-size="600,400" data-will-save="saveRow">
<input type="file"/>
</div>
JS
function addThumb(rowID) {
//$('.slim').attr('data-meta-data-row', rowID);
window.row = rowID;
$("#imageManager").modal('show');
}
function saveRow(data, ready) {
data.meta.row = window.row;
ready(data);
}

Related

Codeigniter File Validation Not Working

Why is that form validation still return an error even though the input file is not empty
Here's my controller together with my callback function
public function add_post()
{
$validation = array (
array(
'field' => 'post_title',
'label' => 'Post title',
'rules' => 'trim|required|alpha_numeric_spaces'
),
array(
'field' => 'post_desc',
'label' => 'Post Description',
'rules' => 'trim|required|alpha_numeric_spaces'
),
array(
'field' => 'post_content',
'label' => 'Post content',
'rules' => 'trim|required'
),
array(
'field' => 'headerimage',
'label' => 'File',
'rules' => 'required|callback_file_check'
)
);
$this->form_validation->set_rules($validation);
if($this->form_validation->run()===FALSE)
{
$info['errors'] = validation_errors();
$info['success'] = false;
}
else
{
$this->save_image();
$datetime = $this->get_time();
$data = array(
"post_title" => $this->input->post('post_title'),
"post_content" => $this->input->post('post_content'),
"post_image" => $this->uploadFileName,
"post_created" => $datetime
);
$this->Blog_model->add_post($data);
$info['success'] = true;
$info['message'] = "Successfully added blog post";
}
$this->output->set_content_type('application/json')->set_output(json_encode($info));
}
Here's the form mark-up
<?php echo form_open_multipart('#',array("class"=>"form-horizontal","id"=>"blogform")); ?>
<div class="row">
<div class="col-md-6">
<input type="text" placeholder="Enter your post title" name="post_title" class="form-control">
</div>
<div class="col-md-6 form-group">
<label for="file" class="control-label col-md-4">Select header image:</label>
<div class="col-md-8">
<input type="file" id="header" name="headerimage" accept="image/*" />
</div>
</div>
</div>
<input type="text" placeholder="Enter your post description" name="post_desc" class="form-control">
<label class="control-label text-muted">Post Body:</label>
<div>
<textarea id="post_content"></textarea>
</div>
<button class="btn btn-default pull-right" type="button" id="save-post"><i class="fa fa-save"></i> Save Post</button>
<div class="clearfix"></div>
<?php echo form_close(); ?>
I call the add_post controller function through AJAX.
$(document).on('click','#save-post',function(){
$post_content = $('#post_content').summernote('code');
$.ajax({
url:site_url('Blog/add_post'),
data: $('#blogform').serialize() + "&post_content=" + $post_content,
type: "POST",
dataType: 'json',
encode: true,
success: function(data){
if(!data.success){
if(data.errors){
$('#blog-message').html(data.errors).addClass('alert alert-danger');
}
}else{
alert(data.message);
}
}
});
});
I don't understand why validation is not working properly or I think the controller doesn't get the input file.
File upload data is not stored in the $_POST array, so cannot be validated using CodeIgniter's form_validation library. File uploads are available to PHP using the $_FILES array.
if (empty($_FILES['headerimage']['name']))
{
$this->form_validation->set_rules('headerimage', 'file', 'required');
// OR
$this->form_validation->set_rules('headerimage', 'file', 'trim|required');
}
OR you can use below system/application/libraries/MY_form_validation.php
Example :
$this->form_validation->set_rules(
// Field Name
$file_field_name ,
// Label
"YOUR FILE LAEBL",
// Rules
"file_required|file_min_size[10KB]|file_max_size[500KB]|file_allowed_type[jpg,jpeg]|file_image_mindim[50,50]|file_image_maxdim[400,300]"
);
MY_form_validation.php
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
/*
* Rules supported:
* file_required
* file_allowed_type[type]
* file_disallowed_type[type]
* file_size_min[size]
* file_size_max[size]
* file_image_mindim[x,y]
* file_image_maxdim[x,y]
*/
class MY_Form_validation extends CI_Form_validation {
function __construct()
{
parent::CI_Form_validation();
}
function set_rules($field, $label = '', $rules = '')
{
if(count($_POST)===0 AND count($_FILES) > 0)//it will prevent the form_validation from working
{
//add a dummy $_POST
$_POST['DUMMY_ITEM'] = '';
parent::set_rules($field,$label,$rules);
unset($_POST['DUMMY_ITEM']);
}
else
{
//we are safe just run as is
parent::set_rules($field,$label,$rules);
}
}
function run($group='')
{
$rc = FALSE;
log_message('DEBUG','called MY_form_validation:run()');
if(count($_POST)===0 AND count($_FILES)>0)//does it have a file only form?
{
//add a dummy $_POST
$_POST['DUMMY_ITEM'] = '';
$rc = parent::run($group);
unset($_POST['DUMMY_ITEM']);
}
else
{
//we are safe just run as is
$rc = parent::run($group);
}
return $rc;
}
function file_upload_error_message($error_code)
{
switch ($error_code)
{
case UPLOAD_ERR_INI_SIZE:
return 'The uploaded file exceeds the upload_max_filesize directive in php.ini';
case UPLOAD_ERR_FORM_SIZE:
return 'The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form';
case UPLOAD_ERR_PARTIAL:
return 'The uploaded file was only partially uploaded';
case UPLOAD_ERR_NO_FILE:
return 'No file was uploaded';
case UPLOAD_ERR_NO_TMP_DIR:
return 'Missing a temporary folder';
case UPLOAD_ERR_CANT_WRITE:
return 'Failed to write file to disk';
case UPLOAD_ERR_EXTENSION:
return 'File upload stopped by extension';
default:
return 'Unknown upload error';
}
}
function _execute($row, $rules, $postdata = NULL, $cycles = 0)
{
log_message('DEBUG','called MY_form_validation::_execute ' . $row['field']);
//changed based on
//http://codeigniter.com/forums/viewthread/123816/P10/#619868
if(isset($_FILES[$row['field']]))
{// it is a file so process as a file
log_message('DEBUG','processing as a file');
$postdata = $_FILES[$row['field']];
//before doing anything check for errors
if($postdata['error'] !== UPLOAD_ERR_OK)
{
$this->_error_array[$row['field']] = $this->file_upload_error_message($postdata['error']);
return FALSE;
}
$_in_array = FALSE;
// If the field is blank, but NOT required, no further tests are necessary
$callback = FALSE;
if ( ! in_array('file_required', $rules) AND $postdata['size']==0)
{
// Before we bail out, does the rule contain a callback?
if (preg_match("/(callback_\w+)/", implode(' ', $rules), $match))
{
$callback = TRUE;
$rules = (array('1' => $match[1]));
}
else
{
return;
}
}
foreach($rules as $rule)
{
/// COPIED FROM the original class
// Is the rule a callback?
$callback = FALSE;
if (substr($rule, 0, 9) == 'callback_')
{
$rule = substr($rule, 9);
$callback = TRUE;
}
// Strip the parameter (if exists) from the rule
// Rules can contain a parameter: max_length[5]
$param = FALSE;
if (preg_match("/(.*?)\[(.*?)\]/", $rule, $match))
{
$rule = $match[1];
$param = $match[2];
}
// Call the function that corresponds to the rule
if ($callback === TRUE)
{
if ( ! method_exists($this->CI, $rule))
{
continue;
}
// Run the function and grab the result
$result = $this->CI->$rule($postdata, $param);
// Re-assign the result to the master data array
if ($_in_array == TRUE)
{
$this->_field_data[$row['field']]['postdata'][$cycles] = (is_bool($result)) ? $postdata : $result;
}
else
{
$this->_field_data[$row['field']]['postdata'] = (is_bool($result)) ? $postdata : $result;
}
// If the field isn't required and we just processed a callback we'll move on...
if ( ! in_array('file_required', $rules, TRUE) AND $result !== FALSE)
{
return;
}
}
else
{
if ( ! method_exists($this, $rule))
{
// If our own wrapper function doesn't exist we see if a native PHP function does.
// Users can use any native PHP function call that has one param.
if (function_exists($rule))
{
$result = $rule($postdata);
if ($_in_array == TRUE)
{
$this->_field_data[$row['field']]['postdata'][$cycles] = (is_bool($result)) ? $postdata : $result;
}
else
{
$this->_field_data[$row['field']]['postdata'] = (is_bool($result)) ? $postdata : $result;
}
}
continue;
}
$result = $this->$rule($postdata, $param);
if ($_in_array == TRUE)
{
$this->_field_data[$row['field']]['postdata'][$cycles] = (is_bool($result)) ? $postdata : $result;
}
else
{
$this->_field_data[$row['field']]['postdata'] = (is_bool($result)) ? $postdata : $result;
}
}
//this line needs testing !!!!!!!!!!!!! not sure if it will work
//it basically puts back the tested values back into $_FILES
//$_FILES[$row['field']] = $this->_field_data[$row['field']]['postdata'];
// Did the rule test negatively? If so, grab the error.
if ($result === FALSE)
{
if ( ! isset($this->_error_messages[$rule]))
{
if (FALSE === ($line = $this->CI->lang->line($rule)))
{
$line = 'Unable to access an error message corresponding to your field name.';
}
}
else
{
$line = $this->_error_messages[$rule];
}
// Is the parameter we are inserting into the error message the name
// of another field? If so we need to grab its "field label"
if (isset($this->_field_data[$param]) AND isset($this->_field_data[$param]['label']))
{
$param = $this->_field_data[$param]['label'];
}
// Build the error message
$message = sprintf($line, $this->_translate_fieldname($row['label']), $param);
// Save the error message
$this->_field_data[$row['field']]['error'] = $message;
if ( ! isset($this->_error_array[$row['field']]))
{
$this->_error_array[$row['field']] = $message;
}
return;
}
}
}
else
{
log_message('DEBUG','Called parent _execute');
parent::_execute($row, $rules, $postdata,$cycles);
}
}
/**
* Future function. To return error message of choice.
* It will use $msg if it cannot find one in the lang files
*
* #param string $msg the error message
*/
function set_error($msg)
{
$CI =& get_instance();
$CI->lang->load('upload');
return ($CI->lang->line($msg) == FALSE) ? $msg : $CI->lang->line($msg);
}
/**
* tests to see if a required file is uploaded
*
* #param mixed $file
*/
function file_required($file)
{
if($file['size']===0)
{
$this->set_message('file_required','Uploading a file for %s is required.');
return FALSE;
}
return TRUE;
}
/**
* tests to see if a file is within expected file size limit
*
* #param mixed $file
* #param mixed $max_size
*/
function file_size_max($file,$max_size)
{
$max_size_bit = $this->let_to_bit($max_size);
if($file['size']>$max_size_bit)
{
$this->set_message('file_size_max',"%s is too big. (max allowed is $max_size)");
return FALSE;
}
return true;
}
/**
* tests to see if a file is bigger than minimum size
*
* #param mixed $file
* #param mixed $min_size
*/
function file_size_min($file,$min_size)
{
$max_size_bit = $this->let_to_bit($max_size);
if($file['size']<$min_size_bit)
{
$this->set_message('file_size_min',"%s is too small. (Min allowed is $max_size)");
return FALSE;
}
return true;
}
/**
* tests the file extension for valid file types
*
* #param mixed $file
* #param mixed $type
*/
function file_allowed_type($file,$type)
{
//is type of format a,b,c,d? -> convert to array
$exts = explode(',',$type);
//is $type array? run self recursively
if(count($exts)>1)
{
foreach($exts as $v)
{
$rc = $this->file_allowed_type($file,$v);
if($rc===TRUE)
{
return TRUE;
}
}
}
//is type a group type? image, application, word_document, code, zip .... -> load proper array
$ext_groups = array();
$ext_groups['image'] = array('jpg','jpeg','gif','png');
$ext_groups['application'] = array('exe','dll','so','cgi');
$ext_groups['php_code'] = array('php','php4','php5','inc','phtml');
$ext_groups['word_document'] = array('rtf','doc','docx');
$ext_groups['compressed'] = array('zip','gzip','tar','gz');
if(array_key_exists($exts[0],$ext_groups))
{
$exts = $ext_groups[$exts[0]];
}
//get file ext
$file_ext = strtolower(strrchr($file['name'],'.'));
$file_ext = substr($file_ext,1);
if(!in_array($file_ext,$exts))
{
$this->set_message('file_allowed_type',"%s should be $type.");
return false;
}
else
{
return TRUE;
}
}
function file_disallowed_type($file,$type)
{
$rc = $this->file_allowed_type($file,$type);
if(!$rc)
{
$this->set_message('file_disallowed_type',"%s cannot be $type.");
}
return $rc;
}
//http://codeigniter.com/forums/viewthread/123816/P20/
/**
* given an string in format of ###AA converts to number of bits it is assignin
*
* #param string $sValue
* #return integer number of bits
*/
function let_to_bit($sValue)
{
// Split value from name
if(!preg_match('/([0-9]+)([ptgmkb]{1,2}|)/ui',$sValue,$aMatches))
{ // Invalid input
return FALSE;
}
if(empty($aMatches[2]))
{ // No name -> Enter default value
$aMatches[2] = 'KB';
}
if(strlen($aMatches[2]) == 1)
{ // Shorted name -> full name
$aMatches[2] .= 'B';
}
$iBit = (substr($aMatches[2], -1) == 'B') ? 1024 : 1000;
// Calculate bits:
switch(strtoupper(substr($aMatches[2],0,1)))
{
case 'P':
$aMatches[1] *= $iBit;
case 'T':
$aMatches[1] *= $iBit;
case 'G':
$aMatches[1] *= $iBit;
case 'M':
$aMatches[1] *= $iBit;
case 'K':
$aMatches[1] *= $iBit;
break;
}
// Return the value in bits
return $aMatches[1];
}
/**
* returns false if image is bigger than the dimensions given
*
* #param mixed $file
* #param array $dim
*/
function file_image_maxdim($file,$dim)
{
log_message('debug','MY_form_validation:file_image_maxdim ' . $dim);
$dim = explode(',',$dim);
if(count($dim)!==2)
{
//bad size given
$this->set_message('file_image_maxdim','%s has invalid rule expected similar to 150,300 .');
return FALSE;
}
log_message('debug','MY_form_validation:file_image_maxdim ' . $dim[0] . ' ' . $dim[1]);
//get image size
$d = $this->get_image_dimension($file['tmp_name']);
log_message('debug',$d[0] . ' ' . $d[1]);
if(!$d)
{
$this->set_message('file_image_maxdim','%s dimensions was not detected.');
return FALSE;
}
if($d[0] < $dim[0] && $d[1] < $dim[1])
{
return TRUE;
}
$this->set_message('file_image_maxdim','%s image size is too big.');
return FALSE;
}
/**
* returns false is the image is smaller than given dimension
*
* #param mixed $file
* #param array $dim
*/
function file_image_mindim($file,$dim)
{
$dim = explode(',',$dim);
if(count($dim)!==2)
{
//bad size given
$this->set_message('file_image_mindim','%s has invalid rule expected similar to 150,300 .');
return FALSE;
}
//get image size
$d = $this->get_image_dimension($file['tmp_name']);
if(!$d)
{
$this->set_message('file_image_mindim','%s dimensions was not detected.');
return FALSE;
}
log_message('debug',$d[0] . ' ' . $d[1]);
if($d[0] > $dim[0] && $d[1] > $dim[1])
{
return TRUE;
}
$this->set_message('file_image_mindim','%s image size is too big.');
return FALSE;
}
/**
* attempts to determine the image dimension
*
* #param mixed $file_name path to the image file
* #return array
*/
function get_image_dimension($file_name)
{
log_message('debug',$file_name);
if (function_exists('getimagesize'))
{
$D = #getimagesize($file_name);
return $D;
}
return FALSE;
}
}
/* End of file MY_form_validation.php */
/* Location: ./system/application/libraries/MY_form_validation.php */
For required file validation you can set validation as follow:
if (empty($_FILES['headerimage']['name']))
{
$this->form_validation->set_rules('headerimage', 'File', 'required');
}
Remove:
array(
'field' => 'headerimage',
'label' => 'File',
'rules' => 'required|callback_file_check'
)

PHP check for empty inputs in form (both file and text)

Im have some trubbel trying to make a PHP script to check if any text(or someting else) input are empty AND at the same time check if any of the file input are empty.
The code use like some frameworks a $rule where you write the rules for the inputs
Example:
$rule = array(
"title" => "required|minLength:5",
"myFile" => "required"
);
I have this function there been looped for each input there are
foreach ($rules as $item => $ruleset) {
// required|email|min:8
$ruleset = explode('|', $ruleset);
foreach ($ruleset as $rule) {
$pos = strpos($rule, ':');
if ($pos !== false) {
$parameter = substr($rule, $pos + 1);
$rule = substr($rule, 0, $pos);
}
else {
$parameter = '';
}
// Example of this output: validateEmail($item, $value, $param)
$methodName = 'validate' . ucfirst($rule);
$value = isset($data[$item]) ? $data[$item] : NULL;
if (method_exists($this, $methodName)) {
$this->$methodName($item, $value, $parameter) or $valid = false;
}
}
}
// Validate the $value of $item to see if it is present and not empty
private function validateRequired ($item, $value)
{
if (empty($value))
{
$this->errors[$item][] = 'The ' . $item . ' field is required';
return false;
}
return true;
}
it work, but as we know, a file input need to been check using a $_FILES,
what can I do???
Your question is quite unclear how you're trying to use all those code pieces together, especially the validateRequired() function. But given the current scenario, you should add type attribute value in $rules array as well.
$rules = array(
"title" => "required|minLength:5|type:text",
"myFile" => "required|type:file"
);
And process your form fields based on the type of the field. However, I'd suggest you to refactor your business logic using the following $rules array,
$rules = array(
'title' => array(
'required' => true,
'minLength' => 5,
'type' => 'text'
),
'myFile' => array(
'required' => true,
'type' => 'file'
)
);
With the above $rules array, it would be lot easier for you to process your form input fields. So your foreach loop would be something like this:
foreach($rules as $item => $rule){
switch($rule['type']){
case 'text':
if($rule['required']){
if(!empty($_POST[$item]) && strlen($_POST[$item]) >= $rule['minLength']){
// SUCCESS: The text field complies with required and minLength conditions
}else{
// ERROR: The text field doesn't comply with required and minLength conditions
}
}else{
// Proceed with your logic
}
break;
case 'file':
if($rule['required']){
if(is_uploaded_file($_FILES[$item]['tmp_name'])){
// SUCCESS: The file field complies with required condition. User has uploaded a file
}else{
// ERROR: The file field doesn't comply with required condition. User hasn't uploaded any file
}
}else{
// Proceed with your logic
}
case 'checkbox':
// your code
}
}

laravel 4 Input::old() is empty

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).

How to edit Magento's API function "items()" to get the ImageUrl of the product

I am trying to get the Image URL of the products by editing the Magento's API items() function. I have used $product-> getImageUrl() to get the URL but I am getting wrong URL.
The URL that I am getting is of the default Image which we place for the products which do not have image(Image Comming Soon like Image's url).
I am calling the function from Android Client using XML-RPC.
I am getting other details of the product correct,but the URL that I am getting for the products is wrong. And, all the URLs of the different products I am getting are same.
FYI, The URL that I am getting in the response is like :
http://192.168.1.237/machinetest/media/catalog/product/cache/0/image/265x/9df78eab33525d08d6e5fb8d27136e95/images/catalog/product/placeholder/image.jpg
The function that I am editing is as followed :
public function items($filters = null, $store = null)
{
$collection = Mage::getModel('catalog/product')->getCollection()
->addStoreFilter($this->_getStoreId($store))
->addAttributeToSelect('name');
if (is_array($filters)) {
try {
foreach ($filters as $field => $value) {
if (isset($this->_filtersMap[$field])) {
$field = $this->_filtersMap[$field];
}
$collection->addFieldToFilter($field, $value);
}
} catch (Mage_Core_Exception $e) {
$this->_fault('filters_invalid', $e->getMessage());
}
}
$result = array();
foreach ($collection as $product) {
//$result[] = $product->getData();
$result[] = array( // Basic product data
'product_id' => $product->getId(),
'sku' => $product->getSku(),
'name' => $product->getName(),
'set' => $product->getAttributeSetId(),
'type' => $product->getTypeId(),
'category_ids'=> $product->getCategoryIds(),
'url_path' => $product-> getImageUrl() // Added the Method here
);
}
return $result;
}
Just write that please try this way..you will get the Solution on the Top
You can able to get Images using this code just go through it and you will get images
public function items($filters = null, $store = null)
{
$collection = Mage::getModel('catalog/product')->getCollection()
->addStoreFilter($this->_getStoreId($store))
->addAttributeToSelect('name');
if (is_array($filters)) {
try {
foreach ($filters as $field => $value) {
if (isset($this->_filtersMap[$field])) {
$field = $this->_filtersMap[$field];
}
$collection->addFieldToFilter($field, $value);
}
} catch (Mage_Core_Exception $e) {
$this->_fault('filters_invalid', $e->getMessage());
}
}
$result = array();
foreach ($collection as $product) {
// $result[] = $product->getData();
$_product = Mage::getModel('catalog/product')->load($product->getId());
$_image=$_product->getImageUrl();
$result[] = array( // Basic product data
'product_id' => $product->getId(),
'sku' => $product->getSku(),
'name' => $product->getName(),
'set' => $product->getAttributeSetId(),
'type' => $product->getTypeId(),
'category_ids'=> $product->getCategoryIds(),
'image_url_path' => $_image
);
}
return $result;
}
hope it's work
if you have any queries tell me i will help you!
I was working with images recently and I believe I have pretty good understanding about it.
I don't think what Josua said is the "real" correct answer. It is good that his answer can solve your problem but I just couldn't stand seeing misleading information.
As for his first option, it is "correct".
Let me break down the code:
Mage_Catalog_Model_Product_Media_Config
public function getMediaUrl($file)
{
$file = $this->_prepareFileForUrl($file);
if(substr($file, 0, 1) == '/') {
return $this->getBaseMediaUrl() . $file;
}
return $this->getBaseMediaUrl() . '/' . $file;
}
public function getBaseMediaUrl()
{
return Mage::getBaseUrl('media') . 'catalog/product';
}
protected function _prepareFileForUrl($file)
{
return str_replace(DS, '/', $file);
}
As you can see, it just simply add media/ + catalog/product + $file.
$file is taken from database, the value will be something like /e/x/example.jpeg
Your uploaded product images are stored inside those folders.
Now, for the problem why $product-> getImageUrl() give you wrong URL is still unknown.
The code that Josua suggest for second option:
$this->helper('catalog/image')
->init($product, $type)
->resize(163, 100);
is "almost" the same with $product->getImageUrl(), it just have difference in resize
Mage_Catalog_Model_Product
public function getImageUrl()
{
return (string)$this->_getImageHelper()->init($this, 'image')->resize(265);
}
So for his second option, it will give the same result with your old code.
I don't know why did he suggest the second option, I think he never check what is behind those functions (not a good idea as it can lead to wrong information)
When you call for $product->getImageUrl(), it will try to load your image from cache if it exists, if not, it will load the image from database (for the path and then will look for your correct image from media folder) and create the cache. If it is unable to find the image or an error occurred, it will get the placeholder image.
My suggestion is to check if there is an exception thrown. You need to use your old code $product->getImageUrl(). Open your app/code/core/Mage/Catalog/Helper/Image.php
Then go to:
Mage_Catalog_Helper_Image
public function __toString()
{
try {
if( $this->getImageFile() ) {
$this->_getModel()->setBaseFile( $this->getImageFile() );
} else {
$this->_getModel()->setBaseFile( $this->getProduct()->getData($this->_getModel()->getDestinationSubdir()) );
}
if( $this->_getModel()->isCached() ) {
return $this->_getModel()->getUrl();
} else {
if( $this->_scheduleRotate ) {
$this->_getModel()->rotate( $this->getAngle() );
}
if ($this->_scheduleResize) {
$this->_getModel()->resize();
}
if( $this->getWatermark() ) {
$this->_getModel()->setWatermark($this->getWatermark());
}
$url = $this->_getModel()->saveFile()->getUrl();
}
} catch( Exception $e ) {
//put log to show error message
Mage::log($e->getMessage());
$url = Mage::getDesign()->getSkinUrl($this->getPlaceholder());
}
return $url;
}
Put Mage::log($e->getMessage()); to log if there is an exception thrown. Most likely your placeholder image is called because there was an exception thrown.
It is just a suggestion from me to ensure there is nothing's wrong with your image / other things as in fact you have solved your problem by directly get the image from media/catalog/product/...
Another correction for Josua's code:
Notice the $full_product = Mage::getModel('catalog/product')->load($product_id);
It is absolutely unnecessary since inside foreach($collection as $product), the product object will be loaded, so another load of product is unnecessary (also $product_id is undefined)
UPDATE, just fixing your code:
public function items($filters = null, $store = null)
{
$collection = Mage::getModel('catalog/product')->getCollection()
->addStoreFilter($this->_getStoreId($store))
->addAttributeToSelect(array('name','image'));
//->addAttributeToSelect('name'); add another select, either image / small_image / thumbnail, modify it as you need
if (is_array($filters)) {
try {
foreach ($filters as $field => $value) {
if (isset($this->_filtersMap[$field])) {
$field = $this->_filtersMap[$field];
}
$collection->addFieldToFilter($field, $value);
}
} catch (Mage_Core_Exception $e) {
$this->_fault('filters_invalid', $e->getMessage());
}
}
$result = array();
foreach ($collection as $product) {
//$result[] = $product->getData();
$result[] = array( // Basic product data
'product_id' => $product->getId(),
'sku' => $product->getSku(),
'name' => $product->getName(),
'set' => $product->getAttributeSetId(),
'type' => $product->getTypeId(),
'category_ids'=> $product->getCategoryIds(),
'url_path' => $product-> getImageUrl() // Added the Method here
);
}
return $result;
}
Your code was awesome!
Yes, you can get image url with :
'url_path' => Mage::getModel('catalog/product_media_config')
->getMediaUrl($product->getImage());//getSmallImage(), getThumbnail()
or another option by calling :
$type = 'small_image';
'url_path' => $this->helper('catalog/image')
->init($product, $type)
->resize(163, 100);
can be changed by 'image' small_image' or 'thumbnail'
Default:
Base Image: 265x265 pixel
Small Image: 135x135 pixel
Thumbnail Image: 75x75 pixel
The easier option (detailed):
public function items($filters = null, $store = null)
{
$collection = Mage::getModel('catalog/product')->getCollection()
->addStoreFilter($this->_getStoreId($store))
->addAttributeToSelect('name');
if (is_array($filters)) {
try {
foreach ($filters as $field => $value) {
if (isset($this->_filtersMap[$field])) {
$field = $this->_filtersMap[$field];
}
$collection->addFieldToFilter($field, $value);
}
} catch (Mage_Core_Exception $e) {
$this->_fault('filters_invalid', $e->getMessage());
}
}
$result = array();
foreach ($collection as $product) {
//$result[] = $product->getData();
$full_product = Mage::getModel('catalog/product')->load($product_id);
$result[] = array( // Basic product data
'product_id' => $product->getId(),
'sku' => $product->getSku(),
'name' => $product->getName(),
'set' => $product->getAttributeSetId(),
'type' => $product->getTypeId(),
'category_ids'=> $product->getCategoryIds(),
'url_path' => $full_product->getImageUrl(),
// 'product_path' => $full_product->getProductUrl()
// you can call $full_product->getData();
);
}
return $result;
}

foreach expects an array in a wordpress template

Okay I have installed a theme in wordpress that returns a few errors.
Warning: Invalid argument supplied for foreach() in /home/mvprop/public_html/wp-content/themes/yoo_vox_wp/warp/systems/wordpress.3.0/helpers/system.php on line 339
This problem is resolved on these forums
but I can't understand what the last post is about. The guy posts a bunch of random code that solves the problem. He doesn't specify where it's from or where to put it. Just pastes code that doesn't seem to have to do with anything.
line 334 to the end of the file
function getWidgets($position = null) {
if (empty($this->widgets)) {
foreach (wp_get_sidebars_widgets() as $pos => $ids) {
$this->widgets[$pos] = array();
foreach ($ids as $id) {
$this->widgets[$pos][$id] = $this->getWidget($id);
}
}
}
if (!is_null($position)) {
return isset($this->widgets[$position]) ? $this->widgets[$position] : array();
}
return $this->widgets;
}
/*
Function: displayWidget
Checks if a widget should be displayed
Returns:
Boolean
*/
function displayWidget($widget) {
if (!isset($widget->options['display']) || in_array('*', $widget->options['display'])) return true;
foreach ($this->getQuery() as $q) {
if (in_array($q, $widget->options['display'])) {
return true;
}
}
return false;
}
/*
Function: overrideConfig
Overrides default config based on page
Returns:
Void
*/
function overrideConfig() {
if (!count($this->config_overrides)) return;
foreach ($this->getQuery() as $q) {
if (isset($this->config_overrides[$q])) {
$this->warp->config->parseString($this->config_overrides[$q]);
}
}
}
/*
Function: isBlog
Returns:
Boolean
*/
function isBlog() {
return true;
}
/*
Function: isPreview
Checks for default widgets in theme preview
Returns:
Boolean
*/
function isPreview($position) {
// preview postions
$positions = array('logo', 'right');
return is_preview() && in_array($position, $positions);
}
/*
Function: ajaxSearch
Ajax search callback
Returns:
String
*/
function ajaxSearch(){
global $wp_query;
$result = array('results' => array());
$query = isset($_REQUEST['s']) ? $_REQUEST['s']:"";
if (strlen($query)>=3) {
$wp_query->query_vars['s'] = $query;
$wp_query->is_search = true;
foreach ($wp_query->get_posts() as $post) {
$content = !empty($post->post_excerpt) ? strip_tags(do_shortcode($post->post_excerpt)) : strip_tags(do_shortcode($post->post_content));
if (strlen($content) > 255) {
$content = substr($content, 0, 254).'...';
}
$result['results'][] = array(
'title' => $post->post_title,
'text' => $content,
'url' => get_permalink($post->ID)
);
}
}
die(json_encode($result));
}
/*
Function: _adminInit
Admin init actions
Returns:
Void
*/
function _adminInit() {
if ((defined('DOING_AJAX') && DOING_AJAX) && isset($_POST['warp-ajax-save'])) {
// update option values
foreach ($_POST as $option => $value) {
if (preg_match('/^(warp_|'.preg_quote($this->prefix, '/').')/', $option)) {
update_option($option, $value);
}
}
die();
}
wp_enqueue_script('warp-admin', rtrim(get_bloginfo('template_url'),'/').'/warp/systems/wordpress.3.0/js/wp-admin.js', false, '1.0');
add_action('wp_ajax_save_nav_settings', array($this,'_save_nav_settings'));
add_action('wp_ajax_get_nav_settings', array($this,'_get_nav_settings'));
}
/*
Function: _adminHead
Admin head actions
Returns:
Void
*/
function _adminHead() {
// init vars
$path =& $this->getHelper('path');
$head[] = '<link rel="stylesheet" href="'.$path->url('warp:systems/wordpress.3.0/css/admin.css').'" type="text/css" />';
$head[] = '<script type="text/javascript" src="'.$path->url('warp:systems/wordpress.3.0/js/admin.js').'"></script>';
echo implode("\n", $head);
}
/*
Function: _adminMenu
Admin menu actions
Returns:
Void
*/
function _adminMenu() {
// init vars
$path =& $this->getHelper('path');
$name = $this->xml->document->getElement('name');
$icon = $path->url('warp:systems/wordpress.3.0/images/yoo_icon_16.png');
if (function_exists('add_object_page')) {
add_object_page('', $name->data(), 8, 'warp', false, $icon);
} else {
add_menu_page('', $name->data(), 8, 'warp', false, $icon);
}
add_submenu_page('warp', 'Theme Options', 'Theme Options', 8, 'warp', array($this, '_adminThemeOptions'));
add_submenu_page('warp', 'Widget Options', 'Widget Options', 8, 'warp_widget', array($this, '_adminWidgetOptions'));
}
/*
Function: _adminThemeOptions
Render admin theme options layout
Returns:
Void
*/
function _adminThemeOptions() {
// init vars
$path =& $this->getHelper('path');
$xml =& $this->getHelper('xml');
$http =& $this->getHelper('http');
$check =& $this->getHelper('checksum');
// get warp xml
$warp_xml = $xml->load($path->path('warp:warp.xml'), 'xml', true);
// update check
$update = null;
if ($url = $warp_xml->document->getElement('updateUrl')) {
// get template info
$template = get_template();
$version = $this->xml->document->getElement('version');
$url = sprintf('%s?application=%s&version=%s&format=raw', $url->data(), $template, $version->data());
// only check once a day
if (get_option($this->prefix.'update_check') != date('Y-m-d').' '.$version->data()) {
if ($request = $http->get($url)) {
update_option($this->prefix.'update_check', date('Y-m-d').' '.$version->data());
update_option($this->prefix.'update_data', $request['body']);
}
}
// decode update response
$update = json_decode(get_option($this->prefix.'update_data'));
}
// verify theme files
if (($checksums = $path->path('template:checksums')) && filesize($checksums)) {
$check->verify($path->path('template:'), $log);
} else {
$log = false;
}
echo $this->warp->template->render('admin/theme_options', array('xml' => $this->xml, 'warp_xml' => $warp_xml, 'update' => $update, 'checklog' => $log));
}
/*
Function: _adminWidgetOptions
Render admin widget options layout
Returns:
Void
*/
function _adminWidgetOptions() {
// get position settings
$position_settings = $this->warp->config->get('warp.positions');
// get module settings
$module_settings = array();
$settings = $this->xml->document->getElement('modulesettings');
foreach ($settings->children() as $setting) {
$module_settings[$setting->attributes('name')] = $setting;
}
echo $this->warp->template->render('admin/widget_options', compact('position_settings', 'module_settings'));
}
/*
Function: getMenuItemOptions
Retrieve menu by id
Parameters:
$id - Menu Item ID
Returns:
Array
*/
function getMenuItemOptions($id) {
$menu_settings = array(
'columns' => 1,
'columnwidth' => -1,
'image' => ''
);
if (isset($this->menu_item_options[$id])) {
$menu_settings = array_merge($menu_settings, $this->menu_item_options[$id]);
}
return $menu_settings;
}
/*
Function: _save_nav_settings
Saves menu item settings
Returns:
Void
*/
function _save_nav_settings() {
if (isset($_POST['menu-item'])) {
$menu_item_settings = $this->menu_item_options;
foreach ($_POST['menu-item'] as $itemId=>$settings){
$menu_item_settings[$itemId] = $settings;
}
update_option($this->prefix.'menu-items', $menu_item_settings);
$this->menu_item_options = $menu_item_settings;
}
die();
}
/*
Function: _get_nav_settings
Returns menu item settings as json
Returns:
Boolean
*/
function _get_nav_settings() {
die(json_encode($this->menu_item_options));
}
}
/*
Function: mb_strpos
mb_strpos function for servers not using the multibyte string extension
*/
if (!function_exists('mb_strpos')) {
function mb_strpos($haystack, $needle, $offset = 0) {
return strpos($haystack, $needle, $offset);
}
}
Basically what this warning message tells you is that the variable you're passing into your foreach is not an array or object. Make sure your variable is valid by testing it ( is_array($var) or is_object($var) ) or placing this block of code in a try-catch.
If $var is supposed to be an array, you should also initialize it just to be certain.
$var = Array();
.
. // code that may change the data type of $var
.
if (is_array($var)) {
foreach($var as $v) {
//code here
}
}
From the manual at http://php.net/manual/en/control-structures.foreach.php:
The foreach construct provides an easy way to iterate over arrays. foreach works only on arrays and objects, and will issue an error when you try to use it on a variable with a different data type or an uninitialized variable.

Categories