Jump to content

Only variables should be passed by reference


tobimichigan

Recommended Posts

Here's the code,

function add_input($label='',$id='',$editable=true) {
		global $global_db_engine;
		$max_length_str='';
		
		if((string)$label==='') {
			$label=' ';			
		}
		
		if(is_array($id)) {
			$input_element='';

			foreach($id as $element_item_key=>$element_item_value) {
				$width=0;
				$caption='';
				
				if((string)$this->source!=='') {
					if(is_int($element_item_key)) {
						// Array provided as plain strings; key is therefore numeric
						$column_name=$element_item_value;
					} else {
						// Array provided as key/value pair - element id is the key
						$column_name=$element_item_key;
						
						// Determine any other settings from the value list
						if(is_array($element_item_value)) {
							if(array_key_exists('width',$element_item_value)) {
								$width=$element_item_value['width'];
							}
							if(array_key_exists('caption',$element_item_value)) {
								$caption=$element_item_value['caption'];
							}
						}
					}
					$value=$this->source_row[$this->source][$column_name];
				}
				
				if((int)$width===0) {
					$width=(400/count($id))-4;
				}

				if($element_item_key!==end(array_keys($id))) {
					$margin='4';
				} else {
					$margin='0';
				}
				
				if(array_key_exists('required',$global_db_engine->db_spec[$this->source]['columns'][$column_name])
				&&$global_db_engine->db_spec[$this->source]['columns'][$column_name]['required']===true) {
					$caption.='<span class="required">*</span>';
				}
				
				if(array_key_exists('help',$element_item_value)) {
					$caption.=" <a href=\"#\" title=\"{$element_item_value['help']}\" tabindex=\"999\">?</a>";
				}

				if($this->validation_failures!==null&&is_array($this->validation_failures)&&array_key_exists($this->source,$this->validation_failures)&&array_key_exists($column_name,$this->validation_failures[$this->source])) {
					// Previously failed validation
					$input_element.=$this->_create_input_control($this->source,$column_name,$value,"width:{$width}px;margin-right:{$margin}px;",$caption,'required_error');
				} else {
					$input_element.=$this->_create_input_control($this->source,$column_name,$value,"width:{$width}px;margin-right:{$margin}px;",$caption);
				}
			}
		} else {
			$width=400;
			
			if(array_key_exists('required',$global_db_engine->db_spec[$this->source]['columns'][$id])
			&&$global_db_engine->db_spec[$this->source]['columns'][$id]['required']===true) {
				$label.='<span class="required">*</span>';
			}

			$value='';
			if((string)$id!=='') {
				$value=$this->source_row[$this->source][$id];

				if($editable===false) {
					$input_element="<strong>".htmlspecialchars($value, ENT_COMPAT, 'UTF-8')."</strong>\n";
				} else {
					if($this->validation_failures!==null&&is_array($this->validation_failures)&&array_key_exists($this->source,$this->validation_failures)&&array_key_exists($id,$this->validation_failures[$this->source])) {
						// Previously failed validation
						$input_element=$this->_create_input_control($this->source,$id,$value,"width:{$width}px;",'','required_error');
					} else {
						$input_element=$this->_create_input_control($this->source,$id,$value,"width:{$width}px;");
					}
				}
			}
		}
		//$input_element.='['.$global_db_engine->db_spec[$this->source]['columns'][$id]['type'].']';
		$label=str_replace('|','<br>',$label);
	
		$label=str_replace('[','<span class="subtle">',$label);
		$label=str_replace(']','</span>',$label);

		$this->form_rows[]="\t<tr><td class=\"label\">{$label}</td><td>{$input_element}</td><tr>\n";
	}

 

The referred line here is

if($element_item_key!==end(array_keys($id))) {
					$margin='4';
				} else {
					$margin='0';
				}

The error says "Only variables should be passed by reference" . Can any help? :confused:

Link to comment
Share on other sites

ok thanks for the reply teynon. much appreciated. I implemented your corrections thus:

$last=end(array_keys($id));//error pointer now here
				if($element_item_key!==$last) {
					$margin='4';
				} else {
					$margin='0';
				}

Now the error pointer is now @ $last=end(array_keys($id)), still indicating "Only variables should be passed by reference in C:\xampp\htdocs\components\web_form.php on line 238"

 

Any better ideas?

Link to comment
Share on other sites

I think your problem may be in your formatting. You are using things like this:

if(array_key_exists('required',$global_db_engine->db_spec[$this->source]['columns'][$column_name])
&&$global_db_engine->db_spec[$this->source]['columns'][$column_name]['required']===true) {
You are not using spaces (which makes your code difficult to read by itself), but on top of that, using this:
&&$global_db_engine
This may be confusing the validator to think you are using &$global_db_engine rather than $global_db_engine. This is the only part of your code that looks anything like you are passing by reference.

 

If you give us the actual line for which you are seeing the error, it would be easier to help.

Edited by haku
Link to comment
Share on other sites

I actually posted the wrong answer the first time.

 

end moves the internal pointer of an array. Meaning that it's arguments are a reference to the array variable. The problem is that he is calling end() on a return value from array_keys. Since this is a value that is returned, it can't be passed as a reference, because it is not really a variable.

 

So as the second one I posted says, return the value of array_keys to a variable, then use end on the variable to move the internal pointer.

 

<?php

    $array = array("apples" => "oranges", "monkeys" => "kittens");
    
    $theKeys = array_keys($array);
    
    if (end($theKeys) == "monkeys") {
        echo "Monkeys are everywhere!";
    }
    echo "End";
Edited by teynon
Link to comment
Share on other sites

Obligatory "never use 'global'" post:

 

Never, ever, ever use 'global' to pass variables to a function.  Why?  Because it makes your code harder to read, harder to edit, and harder to debug.  It creates a hidden, implicit requirement for a function, one that's bound to a certain calling environment.  If you want to pass a variable to a function, use that function's argument list.  That's why it's there.  Since you're already passing $label, $id, and $editable to the function that way, there's no reason not to pass your db in the same way.

Link to comment
Share on other sites

Ok guz, Here's the deal. This code is an open source project. Ever heard of waypoint hr soft? I've attached the raw source code to this post. The test password is admin and user admin. When u log on successfully, it works until u click on add employee which displays but comes with the error described above in the post.

The location of the error script is in the components/web_form.php the script in this code is outlined:

 

<?php
/*  ================================================================================================
	WaypointHR
	www.waypointhr.com
	Copyright 2009 HR-Fundamentals ltd.
----------------------------------------------------------------------------------------------------
	This file is part of WaypointHR.
	
	WaypointHR is free software: you can redistribute it and/or modify it under the terms of the
	GNU General Public License as published by the Free Software Foundation, either version 3 of
	the License, or (at your option) any later version.
	
	WaypointHR is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
	even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
	GNU General Public License for more details.
	
	You should have received a copy of the GNU General Public License along with WaypointHR.
	If not, see <http://www.gnu.org/licenses/>.
----------------------------------------------------------------------------------------------------
	WEB FORMS - BASE, EDIT & VIEW CLASSES
	$Revision: 570 $
	$LastChangedDate: 2009-07-23 03:40:34 +0100 (Thu, 23 Jul 2009) $
================================================================================================= */

/*  ================================================================================================
	BASE CLASS
================================================================================================= */
class web_form_base {
	var $form_rows;
	var $source;
	var $source_row;
	var $source_list;
	var $identity;
	
	function web_form_base($source='',$identity=0,$populated_values=null) {
		global $global_db_engine;
		global $global_params;

		$this->source = $source;

		if ($populated_values === null) {
			// Retrieve values from database
			if ((is_array($source)&&count($source)>0)||(is_string($source)&&(string)$source!=='')) {
				$this->source=$source;
				
				if (is_string($source)) {
					$this->source_row[$source] = $global_db_engine->select_row($source, $identity);

					if(is_int($identity)) {
						$this->identity = $identity;
					} else {
						$this->identity = (int)$this->source_row[$source][$global_db_engine->db_spec[$source]['identity']];
					}
				} elseif (is_array($source)) {
					foreach($source as $source_key=>$source_value) {
						if(is_string($source_key)) {
							$source_alias=$source_key;
						} elseif(isset($source_value)&&is_array($source_value)&&array_key_exists('source',$source_value)) {
							$source_alias = $source_value['source'];
						} else {
							$source_alias = '';
						}
						
						if (isset($source_value)&&is_array($source_value)&&array_key_exists('entity',$source_value)) {
							$source_entity = $source_value['entity'];
						} else {
							$source_entity = $source_alias;
						}

						if (isset($source_value)&&is_array($source_value)&&array_key_exists('filter',$source_value)) {
							$filter=$source_value['filter'];
							// If we are given an integer filter (which would be the table's identity column), select a single row.
							// Otherwise, if the filter array that includes the table's identity column, select a single row.
							// Otherwise, select an array of rows (as the result set could be none, one or more than one row)
							if (is_int($filter)) {
								// Integer specified - use this against the identity column
								$this->source_row[$source_alias] = $global_db_engine->select_row($source_entity, $filter);
							} elseif (is_array($filter)) {
								if (array_key_exists($global_db_engine->db_spec[$source_entity]['identity'],$filter)) {
									$this->source_row[$source_alias] = $global_db_engine->select_row($source_entity, $filter);
								} else {
									if (!array_key_exists('maximum_relations',$global_db_engine->db_spec[$source_entity])
									||(int)$global_db_engine->db_spec[$source_entity]['maximum_relations']>1) {
										$this->source_list[$source_alias] = $global_db_engine->select($source_entity, $filter);
									} else {
										$this->source_row[$source_alias] = $global_db_engine->select_row($source_entity, $filter);
									}
								}
							}
						}
					}
				}
			} else {
				$this->source     = NULL;
				$this->source_row = NULL;
				$this->identity   = 0;
			}
		} else {
			foreach ($populated_values as $populated_key=>$populated_value) {
				if (strpos($populated_key,':') === false) {
					// Row identifier
					$this->source   = $populated_key;
					$this->identity = (int)$populated_value;
				} else {
					// Columnar value
					$qualified_column_name = explode(':',$populated_key);
					$source_name = $qualified_column_name[0];
					$column_name = $qualified_column_name[1];

					if (is_array($populated_value)) {
						$this->source_row[$source_name][$column_name] = $this->_process_array($source_name, $column_name, $populated_value);
					} else {
						$this->source_row[$source_name][$column_name] = $populated_value;
					}

				}
			}
		}
	}
	
	function _process_array($source, $column_name, $post_array) {
		// Combine separated incoming values (e.g. date parts) into a single updatable value
		global $global_db_engine;
		switch($global_db_engine->db_spec[$source]['columns'][$column_name]['type']) {
		case 'date':
			// Concatenate y/m/d, ensuring zeros replace blank spaces (thereby allowing mysql defaults)
			$year=(int)$post_array['year'];
			if($year>0&&$year<100) {
				$year+=2000;
			}
			$month=(int)$post_array['month'];
			$day=(int)$post_array['day'];
			return "{$year}-{$month}-{$day}";
			break;
		default:
			return $post_array;
			break;
		}				
	}
}


/*  ================================================================================================
	EDITABLE WEB FORM CLASS
================================================================================================= */
class web_form_edit extends web_form_base {
	var $parent_identity;
	var $validation_failures;
	var $message;
	var $manual_controls;
	var $post_url;
	var $cancel_url;
	var $toolbar_html;
	var $save_button_text;
	var $remove_button;
	
	function web_form_edit($source,$identity,$parent_identity=0,$validation_failures=null,$populated_values=null) {
		parent::web_form_base($source,$identity,$populated_values);
		$this->parent_identity=(int)$parent_identity;
		$this->validation_failures=$validation_failures;
		$this->message='';
		$this->post_url='';
		$this->cancel_url='';
		$this->toolbar_html='';
	}
	
	function add_title($title,$heading_level=1) {
		if(!is_int($heading_level)) {
			$heading_level=1;
		}
		
		if(is_string($title)) {
			if((int)$heading_level>0) {
				$this->form_rows[]="\t<tr><td colspan=\"2\"><h{$heading_level}>{$title}</h{$heading_level}></td><tr>\n";
			} else {
				$this->form_rows[]="\t<tr><td colspan=\"2\">{$title}</td><tr>\n";
			}
		} elseif(is_array($title)) {
			$callback_parameters=NULL;

			foreach($title['data'] as $callback_column) {
				$callback_parameters[$this->source.'.'.$callback_column]=$this->source_row[$this->source][$callback_column];
			}

			$output=call_user_func($title['fn'],$callback_parameters);
			$this->form_rows[]="\t<tr><td colspan=\"2\"><h{$heading_level}>{$output}</h{$heading_level}></td><tr>\n";
		}
	}
	function add_control($id,$value,$type='hidden') {
		$this->manual_controls[]=array('id'=>$id,'value'=>$value,'type'=>$type);
	}
	function add_text($text,$label='') {	
		if((string)$label!=='') {
			$this->form_rows[]="\t<tr><td>{$label}</td><td>{$text}</td><tr>\n";
		} else {
			$this->form_rows[]="\t<tr><td colspan=\"2\">{$text}</td><tr>\n";
		}
	}
	function add_input($label='',$id='',$editable=true) {
		global $global_db_engine;
		$max_length_str='';
		
		if((string)$label==='') {
			$label=' ';			
		}
		
		if(is_array($id)) {
			$input_element='';

			foreach($id as $element_item_key=>$element_item_value) {
				$width=0;
				$caption='';
				
				if((string)$this->source!=='') {
					if(is_int($element_item_key)) {
						// Array provided as plain strings; key is therefore numeric
						$column_name=$element_item_value;
					} else {
						// Array provided as key/value pair - element id is the key
						$column_name=$element_item_key;
						
						// Determine any other settings from the value list
						if(is_array($element_item_value)) {
							if(array_key_exists('width',$element_item_value)) {
								$width=$element_item_value['width'];
							}
							if(array_key_exists('caption',$element_item_value)) {
								$caption=$element_item_value['caption'];
							}
						}
					}
					$value=$this->source_row[$this->source][$column_name];
				}
				
				if((int)$width===0) {
					$width=(400/count($id))-4;
				}
				$keys=end(array_keys($id));
				if($element_item_key!==$keys) {
					$margin='4';
				} else {
					$margin='0';
				}
				
				if(array_key_exists('required',$global_db_engine->db_spec[$this->source]['columns'][$column_name])
				&&$global_db_engine->db_spec[$this->source]['columns'][$column_name]['required']===true) {
					$caption.='<span class="required">*</span>';
				}
				
				if(array_key_exists('help',$element_item_value)) {
					$caption.=" <a href=\"#\" title=\"{$element_item_value['help']}\" tabindex=\"999\">?</a>";
				}

				if($this->validation_failures!==null&&is_array($this->validation_failures)&&array_key_exists($this->source,$this->validation_failures)&&array_key_exists($column_name,$this->validation_failures[$this->source])) {
					// Previously failed validation
					$input_element.=$this->_create_input_control($this->source,$column_name,$value,"width:{$width}px;margin-right:{$margin}px;",$caption,'required_error');
				} else {
					$input_element.=$this->_create_input_control($this->source,$column_name,$value,"width:{$width}px;margin-right:{$margin}px;",$caption);
				}
			}
		} else {
			$width=400;
			
			if(array_key_exists('required',$global_db_engine->db_spec[$this->source]['columns'][$id])
			&&$global_db_engine->db_spec[$this->source]['columns'][$id]['required']===true) {
				$label.='<span class="required">*</span>';
			}

			$value='';
			if((string)$id!=='') {
				$value=$this->source_row[$this->source][$id];

				if($editable===false) {
					$input_element="<strong>".htmlspecialchars($value, ENT_COMPAT, 'UTF-8')."</strong>\n";
				} else {
					if($this->validation_failures!==null&&is_array($this->validation_failures)&&array_key_exists($this->source,$this->validation_failures)&&array_key_exists($id,$this->validation_failures[$this->source])) {
						// Previously failed validation
						$input_element=$this->_create_input_control($this->source,$id,$value,"width:{$width}px;",'','required_error');
					} else {
						$input_element=$this->_create_input_control($this->source,$id,$value,"width:{$width}px;");
					}
				}
			}
		}
		//$input_element.='['.$global_db_engine->db_spec[$this->source]['columns'][$id]['type'].']';
		$label=str_replace('|','<br>',$label);
	
		$label=str_replace('[','<span class="subtle">',$label);
		$label=str_replace(']','</span>',$label);

		$this->form_rows[]="\t<tr><td class=\"label\">{$label}</td><td>{$input_element}</td><tr>\n";
	}
	function _create_input_control($source_entity, $column, $value, $style, $caption='',$class='') {
		global $global_db_engine;
	
		$max_length_html='';
		$style_html='';

		if(array_key_exists('len',$global_db_engine->db_spec[$source_entity]['columns'][$column])) {
			$max_length=$global_db_engine->db_spec[$source_entity]['columns'][$column]['len'];
			if(is_int($max_length)&&(int)$max_length>0) {
				$max_length_html="maxlength={$global_db_engine->db_spec[$source_entity]['columns'][$column]['len']} ";
			}
		}

		if((string)$style!=='') {
			$style_html="style=\"{$style}\" ";
		}
		
		$id=$source_entity.':'.$column;
		
		switch($global_db_engine->db_spec[$source_entity]['columns'][$column]['type']) {
		case 'date':
			if((string)$value===''||(string)$value==='0000-00-00') {
				$value_day='';
				$value_month='';
				$value_year='';
			} else {
				$date_array=explode('-',$value);
				$value_year=(int)$date_array[0];
				$value_month=(int)$date_array[1];
				$value_day=(int)$date_array[2];
				
				if($value_day===0) {
					$value_day='';
				}
				if($value_month===0) {
					$value_month='';
				}
				if($value_year===0) {
					$value_year='';
				}
			}

			$html="<span class=\"field\">";
			$html.="<input class=\"text\" type=\"text\" name=\"{$id}[day]\" autocomplete=\"off\" style=\"width:30px;margin-right:4px;\" maxlength=\"2\" size=\"6\" value=\"".htmlspecialchars($value_day, ENT_COMPAT, 'UTF-8')."\">\n";
			$html.="<span class=\"caption\">##I18N:day_short##</span>";
			$html.="</span>";
			
			$html.="<span class=\"field\">";
			$html.="<input class=\"text\" type=\"text\" name=\"{$id}[month]\" autocomplete=\"off\" style=\"width:30px;margin-right:4px;\" maxlength=\"2\" size=\"6\" value=\"".htmlspecialchars($value_month, ENT_COMPAT, 'UTF-8')."\">\n";
			$html.="<span class=\"caption\">##I18N:month_short##</span>";
			$html.="</span>";
				
			$html.="<span class=\"field\">";
			$html.="<input class=\"text\" type=\"text\" name=\"{$id}[year]\" autocomplete=\"off\" style=\"width:60px;\" maxlength=\"4\" size=\"10\" value=\"".htmlspecialchars($value_year, ENT_COMPAT, 'UTF-8')."\">\n";
			$html.="<span class=\"caption\">##I18N:year_short##</span>";
			$html.="</span>";

			$caption='';
			break;
		case 'time':
			if((string)$value===''||(int)$value===0) {
				$value_hours='';
				$value_minutes='';
			} else {
				$value_hours=floor($value/100);
				$value_minutes=$value-($value_hours*100);

				if($value_minutes<10) {
					$value_minutes='0'.$value_minutes;
				}
				if($value_hours<10) {
					$value_hours='0'.$value_hours;
				}
			}
			$html="<span class=\"field\">";
			$html.="<input class=\"text\" type=\"text\" name=\"{$id}[hours]\" autocomplete=\"off\" style=\"width:30px;margin-right:4px;\" maxlength=\"2\" size=\"6\" value=\"".htmlspecialchars($value_hours, ENT_COMPAT, 'UTF-8')."\">\n";
			$html.="<span class=\"caption\">##I18N:hour_short##</span>";
			$html.="</span>";
			
			$html.="<span class=\"field\">";
			$html.=": <input class=\"text\" type=\"text\" name=\"{$id}[minutes]\" autocomplete=\"off\" style=\"width:30px;margin-right:4px;\" maxlength=\"2\" size=\"6\" value=\"".htmlspecialchars($value_minutes, ENT_COMPAT, 'UTF-8')."\">\n";
			$html.="<span class=\"caption\">  ##I18N:minute_short##</span>";
			$html.="</span>";
		
			break;
		case 'annual_event':
			if((string)$value===''||(int)$value===0) {
				$value_day='';
				$value_month='';
			} else {
				$value_month=floor($value/100);
				$value_day=$value-($value_month*100);
				if((int)$value_day===0) {
					$value_day='';
				}
			}
			
			$html="<span class=\"field\">";
			$html.="<select name=\"{$id}[month]\" style=\"margin-right:4px;\"><option value=\"0\">Not set</option>";
			for($month=1;$month<=12;$month++) {
				if((int)$value_month===$month) {
					$html.="<option value=\"{$month}\" selected>".(string)date('F',mktime(0,0,0,$month))."</option>";
				} else {
					$html.="<option value=\"{$month}\">".(string)date('F',mktime(0,0,0,$month))."</option>";
				}
			}
			$html.='</select>';

			$html.="<span class=\"caption\">##I18N:month_long##</span>";
			$html.="</span>";

			$html.="<span class=\"field\">";
			$html.="<input class=\"text\" type=\"text\" name=\"{$id}[day]\" autocomplete=\"off\" style=\"width:30px;margin-right:4px;\" maxlength=\"2\" size=\"6\" value=\"".htmlspecialchars($value_day, ENT_COMPAT, 'UTF-8')."\">\n";
			$html.="<span class=\"caption\">##I18N:day_short## (##I18N:or_leave_blank##)</span>";
			$html.="</span>";

			
			break;
		case 'text':
			$html="<span class=\"field\">";
			$html.="<textarea name=\"{$id}\" {$style_html}rows=\"5\">".htmlspecialchars($value, ENT_COMPAT, 'UTF-8')."</textarea>\n";
			$html.="</span>";
			break;
			
		case 'html':
			$html="<span class=\"field\">";
			$html.="<textarea name=\"{$id}\" id=\"html1\" {$style_html}rows=\"5\">".$value."</textarea>\n";
			$html.="</span>";
			break;
			
		case 'fk':
			$related_table=$global_db_engine->db_spec[$source_entity]['columns'][$column]['relation'];
			
			$fk_list=$global_db_engine->select($related_table);
			if(is_array($fk_list)) {
				$html="<span class=\"field\">";
				$html.="<select name=\"{$id}\" {$style_html}>\n";
				$html.="\t<option value=\"0\">-- Select --</option>\n";
				foreach($fk_list as $fk_key=>$fk_row) {
					if($source_entity!==$related_table||(int)$fk_key!==(int)$this->identity) {
						if((int)$value===(int)$fk_row[$global_db_engine->db_spec[$source_entity]['identity']]) {
							$html.="\t<option selected value=\"{$fk_key}\">{$fk_row['dept_name']}</option>\n";
						} else {
							$html.="\t<option value=\"{$fk_key}\">{$fk_row['dept_name']}</option>\n";
						}
					}
				}
				$html.="</select>\n";
				$html.="</span>";
			} else {
				$html="<span class=\"field\">";
				$html.="<select name=\"{$id}\" {$style_html}>\n";
				$html.="\t<option value=\"0\">-- No related items available --</option>\n";
				$html.="</select>\n";
				$html.="</span>";
			}
			break;
		default:
			$html="<span class=\"field\">";
			if($class!=='') {
				$html.="<input class=\"text {$class}\" type=\"text\" name=\"{$id}\" autocomplete=\"off\" {$style_html}{$max_length_html}size=\"55\" value=\"".htmlspecialchars($value, ENT_COMPAT, 'UTF-8')."\">\n";
			} else {
				$html.="<input class=\"text\" type=\"text\" name=\"{$id}\" autocomplete=\"off\" {$style_html}{$max_length_html}size=\"55\" value=\"".htmlspecialchars($value, ENT_COMPAT, 'UTF-8')."\">\n";
			}
			if((string)$caption!=='') {
				$html.="<span class=\"caption\">{$caption}</span>";
			}

			$html.="</span>";
			break;
		}

		return $html;		
	}
	
	function add_message($message) {
		$this->message=$message;
	}
	
	function set_post_url($url) {
		$this->post_url=$url;
	}
	function set_cancel_url($url) {
		$this->cancel_url=$url;
	}
	function set_toolbar($toolbar_html) {
		$this->toolbar_html=$toolbar_html;
	}
	function set_save_button_text($save_button_text) {
		$this->save_button_text=$save_button_text;
	}
	function set_remove_button($remove_button) {
		$this->remove_button=$remove_button;
	}
		
	function render($post_parameter='') {
		global $global_db_engine;
		
		if((int)$this->parent_identity>0) {
			$return_identity=$this->parent_identity;
			$identity=(int)$this->identity;
		} else {
			$return_identity=(int)$this->identity;
			$identity=0;
		}
		
		if($this->post_url!=='') {
			$html="<form action=\"{$this->post_url}\" method=\"post\" name=\"frm\" accept-charset=\"utf-8\">\n";
		} else {			
			if($post_parameter==='') {
				$html="<form action=\"\" method=\"post\" name=\"frm\" onsubmit=\"form_post({$return_identity},{$identity});return false;\" accept-charset=\"utf-8\">\n";
			} else {
				$html="<form action=\"\" method=\"post\" name=\"frm\" onsubmit=\"form_post({$return_identity},{$identity},'{$post_parameter}');return false;\" accept-charset=\"utf-8\">\n";
			}
		}		
		
		if($this->toolbar_html!=='') {
			$html.=$this->toolbar_html;
		}
		
		if(is_array($this->manual_controls)&&count($this->manual_controls)>0) {
			foreach($this->manual_controls as $manual_control) {
				//$html.="<br>{$manual_control['id']}:<input type=\"{$manual_control['type']}\" name=\"{$manual_control['id']}\" value=\"{$manual_control['value']}\">\n";
				$html.="<input type=\"{$manual_control['type']}\" name=\"{$manual_control['id']}\" id=\"{$manual_control['id']}\" value=\"{$manual_control['value']}\">\n";
			}
		}
		
		if(is_array($this->source)) {
			$source_list=$this->source;
		} else {
			$source_list=array(array('source'=>$this->source, 'identity'=>$this->identity));
		}
		foreach($source_list as $source_item) {
			if(is_int($source_item['identity'])&&$source_item['identity']>0) {
				//$html.="<br>ID:";
				$html.="<input type=\"hidden\" name=\"{$source_item['source']}\" value=\"{$source_item['identity']}\">\n";
			} else {
				$relationship='';
				foreach($global_db_engine->db_spec[$source_item['source']]['columns'] as $db_spec_column=>$db_spec_column_spec) {
					if($db_spec_column_spec['type']==='fk') {
						$relationship=$db_spec_column;
						break;
					}
				}
				if($relationship!=='') {
					//$html.="<br>ID(M)[{$source_item['source']}:{$relationship}]:";
					$html.="<input type=\"hidden\" name=\"{$source_item['source']}:{$relationship}\" value=\"{$this->parent_identity}\">\n";
				}
			}
		}
		
		$html.="<table class=\"editable\">\n";
		if($this->message!=='') {
			$html.="\t<tr><td colspan=\"2\" class=\"error-message\">{$this->message}</td></tr>\n";
		}

		foreach($this->form_rows as $form_row) {
			$html.=$form_row;
		}
		
		$html.="\t<tr><td> </td><td>\n";
		
		if($this->toolbar_html==='') {
			$html.="<br><table width=\"100%\">\n\t<tr>\n";
			
			if(!is_null($this->save_button_text)) {
				$save_button_text=$this->save_button_text;
			} else {
				$save_button_text='##I18N:save##';
			}
			$html.="\t\t<td><input type=\"submit\" value=\"{$save_button_text}\">";
			if(!is_null($this->cancel_url)) {
				if($this->cancel_url==='') {
					// Use default (async) link
					$html.=" ##I18N:or## <a href=\"#\" onclick=\"form_cancel({$return_identity});\">##I18N:cancel##</a>";
				} else {
					$html.=" ##I18N:or## <a href=\"{$this->cancel_url}\">##I18N:cancel##</a>";
				}
			}
			$html.="</td>\n";

			if ($this->remove_button===true||($this->remove_button!==false&&(int)$this->parent_identity>0&&(int)$this->identity>0)) {
				// TODO: Support 'remove_url'
				// form_cancel(id to remove,parent id to return to afterwards)
				if (array_key_exists('is_current',$this->source_row[$this->source])&&(int)$this->source_row[$this->source]['is_current']===0) {
					$html.="\t\t<td class=\"rhs\"><input type=\"button\" onclick=\"form_remove('{$this->source}',{$this->parent_identity},{$this->identity});\" value=\"##I18N:restore##\"></td>\n";
				} else {
					$html.="\t\t<td class=\"rhs\"><input type=\"button\" onclick=\"form_remove('{$this->source}',{$this->parent_identity},{$this->identity});\" value=\"##I18N:remove##\"></td>\n";
				}
			} else {
				//$html.="\t\t<td class=\"rhs\"><input disabled=\"true\" type=\"button\" value=\"##I18N:remove##\"></td>\n";
				$html.="\t\t<td> </td>\n";
			}
			$html.="</tr></table>";
		}
		
		$html.=" </td></tr>\n";
		$html.="</table>\n</form>\n";
		
		return $html;
	}
}


/*  ================================================================================================
	ADVANCED INFO VIEW FORM CLASS
================================================================================================= */
class advanced_view extends web_form_base {
	function add_title($title,$heading_level=1) {
		if(!is_int($heading_level)) {
			$heading_level=1;
		}
		$this->form_rows[]="\t<tr><td colspan=\"2\"><h{$heading_level}>{$title}</h{$heading_level}></td><tr>\n";
	}
	
	function add_row($label='',$id='',$column,$callback_function='') {			

		if(!is_array($column)) {	// Allow parameter to be supplied as an array or string
			$column=array($column);
		}
		
		foreach($column as $column_item) {
			if(strpos($column_item,'.')===false) {
				$source_name='';
				$column_name=$column_item;
			} else {
				$qualified_column_name=explode('.',$column_item);
				$source_name=$qualified_column_name[0];
				$column_name=$qualified_column_name[1];
			}
			
			$column_list[]=array('source'=>$source_name,
								 'column_name'=>$column_name);
		}
		
		if(!is_array($this->source)) {	// Allow parameter to be supplied as an array or string
			$source_list=array($this->source);
		} else {
			$source_list=$this->source;
		}

		$index=0;
		foreach($column_list as $column_item) {
			if((string)$column_item['source']!=='') {
				$source_name=$column_item['source'];
			} else {
				$source_name=$this->source;
			}

			if(array_key_exists($source_name,$this->source_row)) {
				$value=$this->source_row[$source_name][$column_item['column_name']];
			} elseif(array_key_exists($source_name,$this->source_list)) {
				$value=NULL;
				$row_identity_column=$global_db_engine->db_spec[$source_name]['identity'];
				foreach($this->source_list[$column_item['source']] as $row) {
					$row_identity=$row[$row_identity_column];
					$value[$row_identity]=$row[$column_item['column_name']];
//array('value'=>$row[$column_item['column_name']],'identity'=>$row_identity);
				}
			} else {
				$value=NULL;	// Column requested is from a source table that doesn't exist
			}

			$column_values[$index]=array('value'=>$value,
										 'source'=>$source_name,
										 'column'=>$column_item['column_name']
										 );
			$index++;
		}

//$add_item_link=debug($column_values);


		if((string)$label!=='') {
			//$add_item_link=debug($column);
			$this->form_rows[]="\t<tr><td class=\"title\">{$label}{$add_item_link}</td><td>{$content_string}</td><tr>\n";
		} else {
			$this->form_rows[]="\t<tr><td colspan=\"2\">NOT IMPLEMENTED: {$content_string}</td><tr>\n";
		}
	}
	
	function render() {
		$html="<table class=\"editable\">\n";
		foreach($this->form_rows as $form_row) {
			$html.=$form_row;
		}

		$html.="</table>\n";

		return $html;
	}
}


/*  ================================================================================================
	INFO VIEW FORM CLASS
================================================================================================= */
class web_form_view extends web_form_base {
		
	function add_title($title,$heading_level=1) {
		if(!is_int($heading_level)) {
			$heading_level=1;
		}
		$this->form_rows[]="\t<tr><td colspan=\"2\"><h{$heading_level}>{$title}</h{$heading_level}></td><tr>\n";
	}
	
	function add_datum($datum_params) {
		$callback='';
		$title='';
		$link='';

		if(array_key_exists('callback',$datum_params)) {
			$callback=$datum_params['callback'];
		}
		if(array_key_exists('title',$datum_params)) {
			$title=$datum_params['title'];
		}
		if(array_key_exists('link',$datum_params)) {
			$link=$datum_params['link'];
		}

		if(is_string($datum_params['data'])) {
			$this->columns[]=$datum_params['data'];
		}elseif(is_array($datum_params['data'])) {
			if(is_array($this->columns)) {
				$this->columns[]=array_merge($this->columns,$datum_params['data']);
			} else {
				$this->columns=$datum_params['data'];
			}
		} else {
			//TODO : Huh? What sort of incoming parameter was that?!
		}
		
$this->add_row($title,$link,$column,$callback_function);
		$this->rows[]=array('title'=>$title,
							'id'=>$link,
							'column'=>$datum_params['data'],
							'callback_function'=>$callback);

	}

	function add_row($label='',$id='',$column,$callback_function='') {
		global $global_db_engine;
		global $global_params;

		$is_callback=false;
		$callback_parameters=NULL;
		if((string)$callback_function!==''&&is_callable($callback_function)===true) {
			$is_callback=true;
		}
		
		// -----------------------------------------------------------------------------
		// STAGE ONE
		// Obtain list of columns, allowing columns to be qualified with a source if required  
		// -----------------------------------------------------------------------------
		if(!is_array($column)) {	// Allow parameter to be supplied as an array or string
			$column=array($column);
		}
		
		foreach($column as $column_item) {
			if(strpos($column_item,'.')===false) {
				$source_name='';
				$column_name=$column_item;
			} else {
				$qualified_column_name=explode('.',$column_item);
				$source_name=$qualified_column_name[0];
				$column_name=$qualified_column_name[1];
			}
			
			$column_list[]=array('source'=>$source_name,
								 'column_name'=>$column_name);
		}

				
		// -----------------------------------------------------------------------------
		// STAGE TWO
		// Retrieve required data from source row or list data structures
		// -----------------------------------------------------------------------------

		if(!is_array($this->source)) {	// Allow parameter to be supplied as an array or string
			$source_list=array($this->source);
		} else {
			$source_list=$this->source;
		}

		$index=0;
		foreach($column_list as $column_item) {
			if((string)$column_item['source']!=='') {
				$source_name=$column_item['source'];
			} else {
				$source_name=$this->source;
			}

			if(array_key_exists($source_name,$this->source_row)) {
				$value=$this->source_row[$source_name][$column_item['column_name']];
			} elseif(array_key_exists($source_name,$this->source_list)) {
				$value=NULL;
				if(isset($this->source[$source_name])&&is_array($this->source[$source_name])&&array_key_exists('entity',$this->source[$source_name])) {
					$row_identity_column=$global_db_engine->db_spec[$this->source[$source_name]['entity']]['identity'];
				} else {
					$row_identity_column=$global_db_engine->db_spec[$source_name]['identity'];
				}
				if(is_array($this->source_list[$column_item['source']])) {
					foreach($this->source_list[$column_item['source']] as $row) {
						$row_identity=$row[$row_identity_column];
						$value[$row_identity]=$row[$column_item['column_name']];
						//array('value'=>$row[$column_item['column_name']],'identity'=>$row_identity);
					}
				}
			} else {
				$value=NULL;	// Column requested is from a source table that doesn't exist
			}

			$column_values[$index]=array('value'=>$value,
										 'source'=>$source_name,
										 'column'=>$column_item['column_name']
										 );
			$index++;
		}


		// -----------------------------------------------------------------------------
		// STAGE THREE
		// Assemble data into HTML, looping and combining arrays if required
		// -----------------------------------------------------------------------------
		$content_string='';
		$add_item_link='';
		if((int)count($column_values)>0) {
			if(is_array($column_values[0]['value'])) {
				// Create an array of parameters (for callback or simple implosion
				$callback_parameters=NULL;
				foreach($column_values as $column_key=>$column_item) {
					foreach($column_item['value'] as $row_key=>$column_values) {
						if($is_callback===true) {
							$callback_parameters[$row_key][$column_item['source'].'.'.$column_item['column']]=htmlspecialchars($column_values, ENT_COMPAT, 'UTF-8');
						} else {
							$callback_parameters[$row_key][$column_item['source'].'.'.$column_item['column']]=$this->_render_column($column_item['source'], $column_item['column'],$column_values);
						}
					}
				}

				// For each top level array element, display a link and the data
				foreach($callback_parameters as $callback_parameters_key=>$callback_parameters_row) {
					if(is_array($id)) {
						// Construct URL
						$url=$id['url'];
						if(array_key_exists('url_concat',$id)) {
							foreach($id['url_concat'] as $url_concat_key=>$url_concat_value) {
								$url_concat_value_resolved=$callback_parameters_key;
								$url.="&{$url_concat_key}={$url_concat_value_resolved}";
							}
						} else {$url.="?";}
						if(array_key_exists('type',$id)&&$id['type']!=='async') {
							if(array_key_exists('style',$id)) {
								$style=$id['style'];
							} else {
								$style='edit';
							}
							$content_string.="<a href=\"{$url}\" class=\"{$style}\">";
						} else {
							//$content_string.='<a href="#" class="edit" onclick="showEditor('.(string)(int)$global_params['qs']['id'].',\''.$id.'\',\''.$global_params['qs']['section'].'\','.(string)(int)$callback_parameters_key.');">';
						}
					} else {
						$content_string.='<a href="#" class="edit" onclick="showEditor('.(string)(int)$global_params['qs']['id'].',\''.$id.'\',\''.$global_params['qs']['section'].'\','.(string)(int)$callback_parameters_key.');">';
					}
					if($is_callback===true) {
						$content_string.=call_user_func($callback_function,$callback_parameters_row);
					} else {
						$content_string.=implode('<br>',$callback_parameters_row);
					}
					
					$content_string.='</a>';
				}
			} else {
				if($is_callback!==true) {
					$content_string_array=null;
					foreach($column_values as $column_item) {
						$content_string_array[]=$this->_render_column($column_item['source'],$column_item['column'],$column_item['value']);
					}
					$content_string=implode('<br>',$content_string_array);
					//array_walk($column_values,$this->_render_column);
					//$content_string=implode('<br>',$content_string_array);
					
				} else {
					$values_exist=false;
					foreach($column_values as $column_item) {
						if($column_item['value']!==null) {
							$callback_parameters[$column_item['source'].'.'.$column_item['column']]=htmlspecialchars($column_item['value'], ENT_COMPAT, 'UTF-8');
							$values_exist=true;
						}
					}
					if($values_exist===true) {
						//$content_string=debug($column_values);
						$content_string=call_user_func($callback_function,$callback_parameters);//$data_element);
					} else {
						$content_string='';
					}
				}

				if(!array_key_exists('section',$global_params['qs'])) {
					$global_params['qs']['section']='';
				}
				$edit_link_tag_open='<a href="#" class="edit" onclick="showEditor('.(string)(int)$global_params['qs']['id'].',\''.$id.'\',\''.$global_params['qs']['section'].'\');">';
				$edit_link_tag_close='</a>';
				
				$content_string=$edit_link_tag_open.$content_string.$edit_link_tag_close;				
			}
		}

		if(is_array($this->source_list)&&array_key_exists($source_name,$this->source_list)) {
			$add_item_link='<br><a href="#" onclick="showEditor('.(string)(int)$global_params['qs']['id'].',\''.$id.'\',\''.$global_params['qs']['section'].'\');">Add new item</a>';
		}

		if((string)$label!=='') {
			$this->form_rows[]="\t<tr><td class=\"title\">{$label}{$add_item_link}</td><td>{$content_string}</td><tr>\n";
		} else {
//TODO: {$add_item_link} - WHERE?
			$this->form_rows[]="\t<tr><td colspan=\"2\">{$content_string}</td><tr>\n";
		}

		return;
	}
	
	function _render_column($source, $column, $value) {
		global $global_db_engine;
		if($source===''||$column==='') {
			if((string)$value===''||(string)$value==='0000-00-00') {
				$output='<span class="subtle">Not set</span>';
			} else {
				$output=htmlspecialchars($value, ENT_COMPAT, 'UTF-8');
			}
			return $output;
		} else {
			switch($global_db_engine->db_spec[$source]['columns'][$column]['type']) {
			case 'date':
				if((string)$value===''||(string)$value==='0000-00-00') {
					$output='<span class="subtle">Not set</span>';
				} else {
					if($value===''||$value==='0000-00-00') {
						$output='<span class="subtle">Not set</span>';
					} else {
						$date_array=explode('-',$value);
						$year=(int)$date_array[0];
						$month=(int)$date_array[1];
						$day=(int)$date_array[2];
						
						$output='';
						$msg=null;
						if($day>0) {
							$output.=(string)$day.' ';
						} else {
							$msg[]='day';
							$output.='<span class="subtle"></span> ';
						}
						if($month>0) {
							$output.=(string)date('F',mktime(0,0,0,$month)).' ';
						} else {
							$msg[]='month';
						}
						if($year>0) {
							$output.=(string)$year;
						} else {
							$msg[]='year';
						}
						
						if(is_array($msg)) {
							$output.='<br><span class="subtle">('.implode('/',$msg).' unknown)</span>';
						}
					}
				}
				return $output;
				break;
				
			default:
				if((string)$value===''||(string)$value==='0000-00-00') {
					$output='<span class="subtle">Not set</span>';
				} else {
					$output=htmlspecialchars($value, ENT_COMPAT, 'UTF-8');
				}
				return $output;
				break;
			}
		}
	}
	
	function render() {
		$html="<table class=\"editable\">\n";
		foreach($this->form_rows as $form_row) {
			$html.=$form_row;
		}

		$html.="</table>\n";

		return $html;
	}
}


/*  ================================================================================================
	FORM RESPONSE HANDLER
================================================================================================= */
class web_form_handler {
	var $source_validation_failure;
	var $processed_data;

	function process_response($force_identity_insert=false) {
		// This is a separate function (rather than being included in the constructor function) to allow return values (success|failure)
		global $global_db_engine;
		global $global_params;

		$source_keys=NULL;
		$values=NULL;
		$result=false;
		$this->source_validation_failure=NULL;
		
		if($force_identity_insert!==true) {
			$force_identity_insert=false;
		}

		// Assemble the incoming parameters into an array dimensioned for each source (allowing stage two - below)
		foreach($global_params['post'] as $post_key=>$post_value) {
			// All incoming post values will be qualified with "[source]:", except for row identifiers
			if(strpos($post_key,':')===false) {
				// Row identifier
				$source_name='';
				$column_name=$post_key;
				
				$source_keys[$post_key]=$post_value;
			} else {
				// Columnar value
				$qualified_column_name=explode(':',$post_key);
				$source_name=$qualified_column_name[0];
				$column_name=$qualified_column_name[1];
				if(is_array($post_value)) {
					$values[$source_name][$column_name]=$this->_process_array($source_name, $column_name, $post_value);
				} else {
					$values[$source_name][$column_name]=$post_value;
				}
				
				// Pre-validation checks
				if(array_key_exists($column_name,$global_db_engine->db_spec[$source_name]['columns'])
				&&array_key_exists('required',$global_db_engine->db_spec[$source_name]['columns'][$column_name])
				&&$global_db_engine->db_spec[$source_name]['columns'][$column_name]['required']===true
				&&(string)$values[$source_name][$column_name]==='') {
					$this->source_validation_failure[$source_name][$column_name]['required']=false;
				}

/*
				if($global_db_engine->db_spec[$source_name]['columns'][$column_name]['type']==='date'
				&&1==2) {
					$this->source_validation_failure[$source_name][$column_name]['date_validation']=false;
				}
*/
			}
		}

		if($this->source_validation_failure!==NULL) {
			// Pre-validation failure
			$this->processed_data=$values;
			return false;
		}

		// Stage two: for each source table dimension, call the updates 
		foreach($values as $source_table=>$source_column_values) {
			if((int)$source_keys[$source_table]>0) {
				$source_column_values[$global_db_engine->db_spec[$source_table]['identity']]=(int)$source_keys[$source_table];
			}
			$result[$source_table]=$global_db_engine->update($source_table,$source_column_values,$force_identity_insert);
		}

		return $result;
	}
	function _process_array($source, $column_name, $post_array) {
		// Combine separated incoming values (e.g. date parts) into a single updatable value
		global $global_db_engine;
		switch($global_db_engine->db_spec[$source]['columns'][$column_name]['type']) {
		case 'date':
			// Concatenate y/m/d, ensuring zeros replace blank spaces (thereby allowing mysql defaults)
			$year=(int)$post_array['year'];
			if($year>0&&$year<100) {
				$year+=2000;
			}
			$month=(int)$post_array['month'];
			$day=(int)$post_array['day'];
			return "{$year}-{$month}-{$day}";
			break;
		case 'time':
			$hours=(int)$post_array['hours'];
			$minutes=(int)$post_array['minutes'];
			if($minutes<10) {
				$minutes='0'.$minutes;
			}
			return "{$hours}{$minutes}";
			break;
		case 'annual_event':
			$month=(int)$post_array['month'];
			$day=(int)$post_array['day'];
			if($day<10) {
				$day='0'.(string)$day;
			}
			return "{$month}{$day}";
		
			break;
		default:
			return $post_array;
			break;
		}				
	}
	function validation_failures() {
		return $this->source_validation_failure;
	}
}
?>

 

I hope this helps to help bring up sharper and more accurate ideas. Thanks again guz of the open source community.

Link to comment
Share on other sites

I think zend needs to look properly into the rules of function declarations and its attendant calls. I mean there should be a level of consistency as php 6.0 approaches. Tenyon, you seem to have some better understanding of what is happening here. Mr. Kevin could u pls be more descriptive of your point by code demo??

Mr. Barand, pls can you make your pointers to this issue more closer to the present call. Much appreciated guz.

Link to comment
Share on other sites

Listen, no one's going to go through hundreds of lines of 3rd party code to try to find your problem.  Especially seeing as, judging by that company's website, it hasn't been worked on since 2009.  And there's no working support forum there.  A quick glance also tells me that the code is fragile since it's:

 

1. Written in PHP 4

2. Uses 'global' everywhere

3. If your code block is accurate, stuffed into one file

 

You're likely better off finding a newer alternative, or coding one up yourself.

 

---

 

Regarding your question to me, a properly written function/method would look like:

 

 

function add_input($global_db_engine, $label = '', $id = '', $editable = true) {
    // blah
}

 

Note how the $global_db_engine variable is now in the function/method's argument list.

Link to comment
Share on other sites

<?php

    $array = array("apples" => "oranges", "monkeys" => "kittens");
    
    $theKeys = array_keys($array);
    
    if (end($theKeys) == "monkeys") {
        echo "Monkeys are everywhere!";
    }
    
    if (end(array_keys($array)) == "monkeys") {
        echo "Monkeys are everywhere!";
    }
    echo "End";

 

For me, this triggers a  Strict standards: Only variables should be passed by reference in C:\wamp\www\test\newEmptyPHP2.php on line 11

 

This error depends on what version of PHP and what error reporting you have enabled.

Link to comment
Share on other sites

I wonder who over there at PHP Development Labs thinks that "ALL" means "MOST" or "NEARLY ALL". ALL should me ALL, IMO. When they did this, I switched to using error_reporting(~0) or error_reporting(-1) (which I am told may not mean the same thing) to make sure I get them ALL*.

 

 

* ALL in this case means THE ENTIRE SET OF ERRORS, WARNINGS, NOTICES, STRICT, etc.

Link to comment
Share on other sites

Failing as in killing the script? It's not killing the script for me. But it might again depend on the PHP version. It makes sense from the C++ standpoint because you can't actually call a function like that. It is reporting a warning, which if something is ajax based, it will kill the ajax request. I didn't read into the code he posted, though, so I may be missing something.

Link to comment
Share on other sites

Failing as in killing the script? It's not killing the script for me.

 

With E_ALL I get both monkey sentences output. With STRICT I only get the one - so I guess it's killing the script.

 

If it can do it without STRICT it should still do it with, but give a warning IMHO

Link to comment
Share on other sites

As to why it wasn't in there before, probably because STRICT doesn't contain actual errors or warnings about current problems, but messages about standards and possible future problems.

 

"Enable to have PHP suggest changes to your code which will ensure the best interoperability and forward compatibility of your code."

 

 

 

I don't see why it would cause the end of the script at that point though.

Link to comment
Share on other sites

I'm running PHP 5.4.3 on my local machine and it doesn't fail, just outputs a warning. Perhaps it's the version you are using or a specific setup?

 

Monkeys are everywhere!


( ! ) Strict standards: Only variables should be passed by reference in C:\wamp\www\test\newEmptyPHP2.php on line 11 Call Stack # Time Memory Function Location 1 0.0003 247856 {main}( ) ..\newEmptyPHP2.php:0

Monkeys are everywhere!End

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.