Fatal error: Non-abstract method NF_Handlers_FieldsetRepeater::isFieldsetData() must contain body in - html

Would really like some help! I tried removing the semicolon but still getting this error:
Fatal error: Non-abstract method NF_Handlers_FieldsetRepeater::isFieldsetData() must contain body in /home/warstdam/public_html/wp-content/plugins/ninja-forms/includes/Handlers/FieldsetRepeater.php on line 173
/**
* Determine if data matches fieldset repeater construct
*
* When given only a submission value without any meta data, check the
* construct of the value to asssert with some level of confidence that
* the value is from a fieldset repeater.
*
* Logic:
* - is submission empty? then NO, we don't assert is fieldset repeater data
* - can the array key be parsed as a fieldset repeater key? If not, then NO…
* - is each value an array with 'id' and 'value' keys,
* and the `id` matches the id of its parent? If not, then NO...
*
* If all the above conditions are met for every entry in the submission,
* we assert that the submission value is that of a fieldset repeater.
*
*
* #param array $submission
* #return boolean
*/
public function isFieldsetData(array $submission); bool
{
$return = true;
// If not array containing data, not fieldset repeater
if (empty($submission)) {
$return = false;
}
foreach($submission as $key=>$submissionValueArray){
$submissionReference = $this->parseFieldsetFieldReference($key);
if(-1===$submissionReference){
$return = false;
}
if(!isset($submissionValueArray['id'])
|| $key!==$submissionValueArray['id']
|| !isset($submissionValueArray['value'])){
$return = false;
}
}
Here is the end of the code
{
$return = [];
if (!is_array($fieldSubmissionValue)) {
return $return;
}
if(''!==$fieldId and []!== $fieldSettings){
$fieldsetLabelLookup = $this->getFieldsetLabels($fieldId, $fieldSettings);
$fieldsetTypeLookup = $this->getFieldsetTypes($fieldId,$fieldSettings);
}else{
$fieldsetLabelLookup = null;
$fieldsetTypeLookup = null;
}
// $completeFieldsetID is in format {fieldsetRepeaterFieldId}{fieldsetDelimiter}{fieldsetFieldId}{submissionIndexDelimiter}{submissionIndex}
foreach ($fieldSubmissionValue as $completeFieldsetId => $incomingValueArray) {
// value is expected to be keyed inside incoming value array
if (isset($incomingValueArray['value'])) {
$value = $incomingValueArray['value'];
} else {
$value = $incomingValueArray;
}
// attempt parsing of fielsetField; if any fail, exit as data is corrupt
$fieldsetWithSubmissionIndex = $this->parseFieldsetFieldReference($completeFieldsetId);
if (0 == $fieldsetWithSubmissionIndex['fieldsetFieldId']) {
return $return;
}
$parsedSubmissionIds = $this->parseSubmissionIndex($fieldsetWithSubmissionIndex['fieldsetFieldId']);
if (-1 === $parsedSubmissionIds['submissionIndex']) {
return $return;
}
$fieldsetFieldId = $parsedSubmissionIds['fieldsetFieldId'];
$submissionIndex = $parsedSubmissionIds['submissionIndex'];
$idKey = $fieldId . $this->fieldsetDelimiter . $fieldsetFieldId;
if(is_null($fieldsetTypeLookup)){
$fieldsetFieldType='';
}else{
$fieldsetFieldType = $fieldsetTypeLookup[$idKey];
}
if(is_null($fieldsetLabelLookup)){
$fieldsetFieldLabel='';
}else{
$fieldsetFieldLabel = $fieldsetLabelLookup[$idKey];
}
$array = [];
$array['value'] = $value;
$array['type'] = $fieldsetFieldType;
$array['label'] = $fieldsetFieldLabel;
$return[$submissionIndex][$fieldsetFieldId] = $array;
}
return $return;
}
}

Looks like a syntax error.
Change ; bool to : bool.
public function isFieldsetData(array $submission): bool

Related

PHP Strict Standards: Declaration of ezSQL_mysql::escape() should be compatible with ezSQLcore::escape() in /home

i have problem about ezSQL_mysql and ezSQLcore, it may be an incompatible version of PHP, I share the code below. what version of Php should I use or what should I do to tailor mysqli? (my php version 5.6 )
codes :
ezSQL_mysql
<?php
/**********************************************************************
* Author: Justin Vincent (jv#jvmultimedia.com)
* Web...: http://twitter.com/justinvincent
* Name..: ezSQL_mysql
* Desc..: mySQL component (part of ezSQL databse abstraction library)
*
*/
/**********************************************************************
* ezSQL error strings - mySQL
*/
$ezsql_mysql_str = array
(
1 => 'Require $dbuser and $dbpassword to connect to a database server',
2 => 'Error establishing mySQL database connection. Correct user/password? Correct hostname? Database server running?',
3 => 'Require $dbname to select a database',
4 => 'mySQL database connection is not active',
5 => 'Unexpected error while trying to select database'
);
/**********************************************************************
* ezSQL Database specific class - mySQL
*/
if ( ! function_exists ('mysql_connect') ) die('<b>Fatal Error:</b> ezSQL_mysql requires mySQL Lib to be compiled and or linked in to the PHP engine');
if ( ! class_exists ('ezSQLcore') ) die('<b>Fatal Error:</b> ezSQL_mysql requires ezSQLcore (ez_sql_core.php) to be included/loaded before it can be used');
class ezSQL_mysql extends ezSQLcore
{
var $dbuser = false;
var $dbpassword = false;
var $dbname = false;
var $dbhost = false;
/**********************************************************************
* Constructor - allow the user to perform a qucik connect at the
* same time as initialising the ezSQL_mysql class
*/
function ezSQL_mysql($dbuser='**', $dbpassword='**', $dbname='**', $dbhost='localhost')
{
$this->dbuser = $dbuser;
$this->dbpassword = $dbpassword;
$this->dbname = $dbname;
$this->dbhost = $dbhost;
}
/**********************************************************************
* Short hand way to connect to mySQL database server
* and select a mySQL database at the same time
*/
function quick_connect($dbuser='**', $dbpassword='**', $dbname='**', $dbhost='localhost')
{
$return_val = false;
if ( ! $this->connect($dbuser, $dbpassword, $dbhost,true) ) ;
else if ( ! $this->select($dbname) ) ;
else $return_val = true;
return $return_val;
}
/**********************************************************************
* Try to connect to mySQL database server
*/
function connect($dbuser='**', $dbpassword='**', $dbhost='localhost')
{
global $ezsql_mysql_str; $return_val = false;
// Must have a user and a password
if ( ! $dbuser )
{
$this->register_error($ezsql_mysql_str[1].' in '.__FILE__.' on line '.__LINE__);
$this->show_errors ? trigger_error($ezsql_mysql_str[1],E_USER_WARNING) : null;
}
// Try to establish the server database handle
else if ( ! $this->dbh = #mysql_connect($dbhost,$dbuser,$dbpassword,true) )
{
$this->register_error($ezsql_mysql_str[2].' in '.__FILE__.' on line '.__LINE__);
$this->show_errors ? trigger_error($ezsql_mysql_str[2],E_USER_WARNING) : null;
}
else
{
$this->dbuser = $dbuser;
$this->dbpassword = $dbpassword;
$this->dbhost = $dbhost;
$return_val = true;
}
return $return_val;
}
/**********************************************************************
* Try to select a mySQL database
*/
function select($dbname='**')
{
global $ezsql_mysql_str; $return_val = false;
// Must have a database name
if ( ! $dbname )
{
$this->register_error($ezsql_mysql_str[3].' in '.__FILE__.' on line '.__LINE__);
$this->show_errors ? trigger_error($ezsql_mysql_str[3],E_USER_WARNING) : null;
}
// Must have an active database connection
else if ( ! $this->dbh )
{
$this->register_error($ezsql_mysql_str[4].' in '.__FILE__.' on line '.__LINE__);
$this->show_errors ? trigger_error($ezsql_mysql_str[4],E_USER_WARNING) : null;
}
// Try to connect to the database
else if ( !#mysql_select_db($dbname,$this->dbh) )
{
// Try to get error supplied by mysql if not use our own
if ( !$str = #mysql_error($this->dbh))
$str = $ezsql_mysql_str[5];
$this->register_error($str.' in '.__FILE__.' on line '.__LINE__);
$this->show_errors ? trigger_error($str,E_USER_WARNING) : null;
}
else
{
include 'sql_for_tr.php';
$this->dbname = $dbname;
$return_val = true;
}
return $return_val;
}
/**********************************************************************
* Format a mySQL string correctly for safe mySQL insert
* (no mater if magic quotes are on or not)
*/
function escape($str)
{
return mysql_escape_string(stripslashes($str));
}
/**********************************************************************
* Return mySQL specific system date syntax
* i.e. Oracle: SYSDATE Mysql: NOW()
*/
function sysdate()
{
return 'NOW()';
}
/**********************************************************************
* Perform mySQL query and try to detirmin result value
*/
function query($query)
{
// Initialise return
$return_val = 0;
// Flush cached values..
$this->flush();
// For reg expressions
$query = trim($query);
// Log how the function was called
$this->func_call = "\$db->query(\"$query\")";
// Keep track of the last query for debug..
$this->last_query = $query;
// Count how many queries there have been
$this->num_queries++;
// Use core file cache function
if ( $cache = $this->get_cache($query) )
{
return $cache;
}
// If there is no existing database connection then try to connect
if ( ! isset($this->dbh) || ! $this->dbh )
{
$this->connect($this->dbuser, $this->dbpassword, $this->dbhost);
$this->select($this->dbname);
}
// Perform the query via std mysql_query function..
$this->result = #mysql_query($query,$this->dbh);
// If there is an error then take note of it..
if ( $str = #mysql_error($this->dbh) )
{
$is_insert = true;
$this->register_error($str);
$this->show_errors ? trigger_error($str,E_USER_WARNING) : null;
return true;
}
// Query was an insert, delete, update, replace
$is_insert = false;
if ( preg_match("/^(insert|delete|update|replace)\s+/i",$query) )
{
$this->rows_affected = #mysql_affected_rows();
// Take note of the insert_id
if ( preg_match("/^(insert|replace)\s+/i",$query) )
{
$this->insert_id = #mysql_insert_id($this->dbh);
}
// Return number fo rows affected
$return_val = $this->rows_affected;
}
// Query was a select
else
{
// Take note of column info
$i=0;
while ($i < #mysql_num_fields($this->result))
{
$this->col_info[$i] = #mysql_fetch_field($this->result);
$i++;
}
// Store Query Results
$num_rows=0;
while ( $row = #mysql_fetch_object($this->result) )
{
// Store relults as an objects within main array
$this->last_result[$num_rows] = $row;
$num_rows++;
}
#mysql_free_result($this->result);
// Log number of rows the query returned
$this->num_rows = $num_rows;
// Return number of rows selected
$return_val = $this->num_rows;
}
// disk caching of queries
$this->store_cache($query,$is_insert);
// If debug ALL queries
$this->trace || $this->debug_all ? $this->debug() : null ;
return $return_val;
}
}
?>
ezSQLcore
<?php
/**********************************************************************
* Author: Justin Vincent (jv#jvmultimedia.com)
* Web...: http://twitter.com/justinvincent
* Name..: ezSQL
* Desc..: ezSQL Core module - database abstraction library to make
* it very easy to deal with databases.
*
*/
/**********************************************************************
* ezSQL Constants
*/
define('EZSQL_VERSION','2.03');
define('OBJECT','OBJECT',true);
define('ARRAY_A','ARRAY_A',true);
define('ARRAY_N','ARRAY_N',true);
define('EZSQL_CORE_ERROR','ezSQLcore can not be used by itself (it is designed for use by database specific modules).');
/**********************************************************************
* Core class containg common functions to manipulate query result
* sets once returned
*/
class ezSQLcore
{
var $trace = false; // same as $debug_all
var $debug_all = false; // same as $trace
var $debug_called = false;
var $vardump_called = false;
var $show_errors = true;
var $num_queries = 0;
var $last_query = null;
var $last_error = null;
var $col_info = null;
var $captured_errors = array();
var $cache_dir = false;
var $cache_queries = false;
var $cache_inserts = false;
var $use_disk_cache = false;
var $cache_timeout = 24; // hours
// == TJH == default now needed for echo of debug function
var $debug_echo_is_on = true;
/**********************************************************************
* Constructor
*/
function ezSQLcore()
{
}
/**********************************************************************
* Connect to DB - over-ridden by specific DB class
*/
function connect()
{
die(EZSQL_CORE_ERROR);
}
/**********************************************************************
* Select DB - over-ridden by specific DB class
*/
function select()
{
die(EZSQL_CORE_ERROR);
}
/**********************************************************************
* Basic Query - over-ridden by specific DB class
*/
function query()
{
die(EZSQL_CORE_ERROR);
}
/**********************************************************************
* Format a string correctly for safe insert - over-ridden by specific
* DB class
*/
function escape()
{
die(EZSQL_CORE_ERROR);
}
/**********************************************************************
* Return database specific system date syntax
* i.e. Oracle: SYSDATE Mysql: NOW()
*/
function sysdate()
{
die(EZSQL_CORE_ERROR);
}
/**********************************************************************
* Print SQL/DB error - over-ridden by specific DB class
*/
function register_error($err_str)
{
// Keep track of last error
$this->last_error = $err_str;
// Capture all errors to an error array no matter what happens
$this->captured_errors[] = array
(
'error_str' => $err_str,
'query' => $this->last_query
);
}
/**********************************************************************
* Turn error handling on or off..
*/
function show_errors()
{
$this->show_errors = true;
}
function hide_errors()
{
$this->show_errors = false;
}
/**********************************************************************
* Kill cached query results
*/
function flush()
{
// Get rid of these
$this->last_result = null;
$this->col_info = null;
$this->last_query = null;
$this->from_disk_cache = false;
}
/**********************************************************************
* Get one variable from the DB - see docs for more detail
*/
function get_var($query=null,$x=0,$y=0)
{
// Log how the function was called
$this->func_call = "\$db->get_var(\"$query\",$x,$y)";
// If there is a query then perform it if not then use cached results..
if ( $query )
{
$this->query($query);
}
// Extract var out of cached results based x,y vals
if ( $this->last_result[$y] )
{
$values = array_values(get_object_vars($this->last_result[$y]));
}
// If there is a value return it else return null
return (isset($values[$x]) && $values[$x]!=='')?$values[$x]:null;
}
/**********************************************************************
* Get one row from the DB - see docs for more detail
*/
function get_row($query=null,$output=OBJECT,$y=0)
{
// Log how the function was called
$this->func_call = "\$db->get_row(\"$query\",$output,$y)";
// If there is a query then perform it if not then use cached results..
if ( $query )
{
$this->query($query);
}
// If the output is an object then return object using the row offset..
if ( $output == OBJECT )
{
return $this->last_result[$y]?$this->last_result[$y]:null;
}
// If the output is an associative array then return row as such..
elseif ( $output == ARRAY_A )
{
return $this->last_result[$y]?get_object_vars($this->last_result[$y]):null;
}
// If the output is an numerical array then return row as such..
elseif ( $output == ARRAY_N )
{
return $this->last_result[$y]?array_values(get_object_vars($this->last_result[$y])):null;
}
// If invalid output type was specified..
else
{
$this->print_error(" \$db->get_row(string query, output type, int offset) -- Output type must be one of: OBJECT, ARRAY_A, ARRAY_N");
}
}
/**********************************************************************
* Function to get 1 column from the cached result set based in X index
* see docs for usage and info
*/
function get_col($query=null,$x=0)
{
// If there is a query then perform it if not then use cached results..
if ( $query )
{
$this->query($query);
}
// Extract the column values
for ( $i=0; $i < count($this->last_result); $i++ )
{
$new_array[$i] = $this->get_var(null,$x,$i);
}
return $new_array;
}
/**********************************************************************
* Return the the query as a result set - see docs for more details
*/
function get_results($query=null, $output = OBJECT)
{
// Log how the function was called
$this->func_call = "\$db->get_results(\"$query\", $output)";
// If there is a query then perform it if not then use cached results..
if ( $query )
{
$this->query($query);
}
// Send back array of objects. Each row is an object
if ( $output == OBJECT )
{
return $this->last_result;
}
elseif ( $output == ARRAY_A || $output == ARRAY_N )
{
if ( $this->last_result )
{
$i=0;
foreach( $this->last_result as $row )
{
$new_array[$i] = get_object_vars($row);
if ( $output == ARRAY_N )
{
$new_array[$i] = array_values($new_array[$i]);
}
$i++;
}
return $new_array;
}
else
{
return null;
}
}
}
/**********************************************************************
* Function to get column meta data info pertaining to the last query
* see docs for more info and usage
*/
function get_col_info($info_type="name",$col_offset=-1)
{
if ( $this->col_info )
{
if ( $col_offset == -1 )
{
$i=0;
foreach($this->col_info as $col )
{
$new_array[$i] = $col->{$info_type};
$i++;
}
return $new_array;
}
else
{
return $this->col_info[$col_offset]->{$info_type};
}
}
}
/**********************************************************************
* store_cache
*/
function store_cache($query,$is_insert)
{
// The would be cache file for this query
$cache_file = $this->cache_dir.'/'.md5($query);
// disk caching of queries
if ( $this->use_disk_cache && ( $this->cache_queries && ! $is_insert ) || ( $this->cache_inserts && $is_insert ))
{
if ( ! is_dir($this->cache_dir) )
{
$this->register_error("Could not open cache dir: $this->cache_dir");
$this->show_errors ? trigger_error("Could not open cache dir: $this->cache_dir",E_USER_WARNING) : null;
}
else
{
// Cache all result values
$result_cache = array
(
'col_info' => $this->col_info,
'last_result' => $this->last_result,
'num_rows' => $this->num_rows,
'return_value' => $this->num_rows,
);
error_log ( serialize($result_cache), 3, $cache_file);
}
}
}
/**********************************************************************
* get_cache
*/
function get_cache($query)
{
// The would be cache file for this query
$cache_file = $this->cache_dir.'/'.md5($query);
// Try to get previously cached version
if ( $this->use_disk_cache && file_exists($cache_file) )
{
// Only use this cache file if less than 'cache_timeout' (hours)
if ( (time() - filemtime($cache_file)) > ($this->cache_timeout*3600) )
{
unlink($cache_file);
}
else
{
$result_cache = unserialize(file_get_contents($cache_file));
$this->col_info = $result_cache['col_info'];
$this->last_result = $result_cache['last_result'];
$this->num_rows = $result_cache['num_rows'];
$this->from_disk_cache = true;
// If debug ALL queries
$this->trace || $this->debug_all ? $this->debug() : null ;
return $result_cache['return_value'];
}
}
}
/**********************************************************************
* Dumps the contents of any input variable to screen in a nicely
* formatted and easy to understand way - any type: Object, Var or Array
*/
function vardump($mixed='')
{
// Start outup buffering
ob_start();
echo "<p><table><tr><td bgcolor=ffffff><blockquote><font color=000090>";
echo "<pre><font face=arial>";
if ( ! $this->vardump_called )
{
echo "<font color=800080><b>ezSQL</b> (v".EZSQL_VERSION.") <b>Variable Dump..</b></font>\n\n";
}
$var_type = gettype ($mixed);
print_r(($mixed?$mixed:"<font color=red>No Value / False</font>"));
echo "\n\n<b>Type:</b> " . ucfirst($var_type) . "\n";
echo "<b>Last Query</b> [$this->num_queries]<b>:</b> ".($this->last_query?$this->last_query:"NULL")."\n";
echo "<b>Last Function Call:</b> " . ($this->func_call?$this->func_call:"None")."\n";
echo "<b>Last Rows Returned:</b> ".count($this->last_result)."\n";
echo "</font></pre></font></blockquote></td></tr></table>".$this->donation();
echo "\n<hr size=1 noshade color=dddddd>";
// Stop output buffering and capture debug HTML
$html = ob_get_contents();
ob_end_clean();
// Only echo output if it is turned on
if ( $this->debug_echo_is_on )
{
echo $html;
}
$this->vardump_called = true;
return $html;
}
/**********************************************************************
* Alias for the above function
*/
function dumpvar($mixed)
{
$this->vardump($mixed);
}
/**********************************************************************
* Displays the last query string that was sent to the database & a
* table listing results (if there were any).
* (abstracted into a seperate file to save server overhead).
*/
function debug()
{
// Start outup buffering
ob_start();
echo "<blockquote>";
// Only show ezSQL credits once..
if ( ! $this->debug_called )
{
echo "<font color=800080 face=arial size=2><b>ezSQL</b> (v".EZSQL_VERSION.") <b>Debug..</b></font><p>\n";
}
if ( $this->last_error )
{
echo "<font face=arial size=2 color=000099><b>Last Error --</b> [<font color=000000><b>$this->last_error</b></font>]<p>";
}
if ( $this->from_disk_cache )
{
echo "<font face=arial size=2 color=000099><b>Results retrieved from disk cache</b></font><p>";
}
echo "<font face=arial size=2 color=000099><b>Query</b> [$this->num_queries] <b>--</b> ";
echo "[<font color=000000><b>$this->last_query</b></font>]</font><p>";
echo "<font face=arial size=2 color=000099><b>Query Result..</b></font>";
echo "<blockquote>";
if ( $this->col_info )
{
// =====================================================
// Results top rows
echo "<table cellpadding=5 cellspacing=1 bgcolor=555555>";
echo "<tr bgcolor=eeeeee><td nowrap valign=bottom><font color=555599 face=arial size=2><b>(row)</b></font></td>";
for ( $i=0; $i < count($this->col_info); $i++ )
{
echo "<td nowrap align=left valign=top><font size=1 color=555599 face=arial>{$this->col_info[$i]->type} {$this->col_info[$i]->max_length}</font><br><span style='font-family: arial; font-size: 10pt; font-weight: bold;'>{$this->col_info[$i]->name}</span></td>";
}
echo "</tr>";
// ======================================================
// print main results
if ( $this->last_result )
{
$i=0;
foreach ( $this->get_results(null,ARRAY_N) as $one_row )
{
$i++;
echo "<tr bgcolor=ffffff><td bgcolor=eeeeee nowrap align=middle><font size=2 color=555599 face=arial>$i</font></td>";
foreach ( $one_row as $item )
{
echo "<td nowrap><font face=arial size=2>$item</font></td>";
}
echo "</tr>";
}
} // if last result
else
{
echo "<tr bgcolor=ffffff><td colspan=".(count($this->col_info)+1)."><font face=arial size=2>No Results</font></td></tr>";
}
echo "</table>";
} // if col_info
else
{
echo "<font face=arial size=2>No Results</font>";
}
echo "</blockquote></blockquote>".$this->donation()."<hr noshade color=dddddd size=1>";
// Stop output buffering and capture debug HTML
$html = ob_get_contents();
ob_end_clean();
// Only echo output if it is turned on
if ( $this->debug_echo_is_on )
{
echo $html;
}
$this->debug_called = true;
return $html;
}
/**********************************************************************
* Naughty little function to ask for some remuniration!
*/
function donation()
{
return "<font size=1 face=arial color=000000>If ezSQL has helped make a donation!? <!--[ go on! you know you want to! ]--></font>";
}
}
?>
i have problem about ezSQL_mysql and ezSQLcore, it may be an incompatible version of PHP, I share the code below. what version of Php should I use or what should I do to tailor mysqli?
what kind of arrangement should I make? thanks for helping.
The problem is that in your implementation you have:
function escape($str)
While in core they have:
function escape()
They need to match exactly. So I suggest that change the signature back in the core file to escape($str)

PhpDoc generating warning

The warning messages generated in the document following is the message seen in all methods inside the document.
Warning: count(): Parameter must be an array or an object that implements Countable in C:\php72\pear\phpDocumentor\vendor\twig\twig\lib\Twig\Extension\Core.php on line 1198 Warning: count(): Parameter must be an array or an object that implements Countable in C:\php72\pear\phpDocumentor\vendor\twig\twig\lib\Twig\Extension\Core.php on line 1198 enter image description here
Ok found the solution.
see link
https://area51.phpbb.com/phpBB/viewtopic.php?t=52691
changed the function in core.php file
/**
* Returns the length of a variable.
*
* #param Twig_Environment $env
* #param mixed $thing A variable
*
* #return int The length of the value
*/
function twig_length_filter(Twig_Environment $env, $thing)
{
if (is_scalar($thing)) {
return mb_strlen($thing, $env->getCharset());
}
if (is_object($thing) && method_exists($thing, '__toString') && !$thing instanceof \Countable) {
return mb_strlen((string) $thing, $env->getCharset());
}
return count($thing);
}
to following
/**
* Returns the length of a variable.
*
* #param Twig_Environment $env
* #param mixed $thing A variable
*
* #return int The length of the value
*/
function twig_length_filter(Twig_Environment $env, $thing)
{
if (null === $thing) {
return 0;
}
if (is_scalar($thing)) {
return mb_strlen($thing, $env->getCharset());
}
if (is_object($thing) && method_exists($thing, '__toString') && !$thing instanceof \Countable) {
return mb_strlen((string) $thing, $env->getCharset());
}
if ($thing instanceof \Countable || is_array($thing)) {
return count($thing);
}
return 1;
}
I have struggled a lot to correct this same error, so I wish to share here the complete solution : what to change and how to edit the phar file :
Copy this script in a file in your phar folder and run it with the php command line with option specified in code :
<?php
//to be run with php -d phar.readonly=Off -f thisFileName
if (ini_get('phar.readonly')==1){
die("\n\nThis script must be run with option -d phar.readonly=Off so that it can write the .phar file\n\n");
}
//the file you want to change
$file = 'vendor/twig/twig/lib/Twig/Extension/Core.php';
//the function in the file you want to change
$oldFunction = '#function twig_length_filter[^{]*[^}]*}#'; //assuming it's still the actual one line function, regex might need updates in the furure
//the replacement function
$newFunction = <<<'funct'
function twig_length_filter(Twig_Environment $env, $thing)
{
if (null === $thing) {
return 0;
}
if (is_scalar($thing)) {
return mb_strlen($thing, $env->getCharset());
}
if (is_object($thing) && method_exists($thing, '__toString') && !$thing instanceof \Countable) {
return mb_strlen((string) $thing, $env->getCharset());
}
if ($thing instanceof \Countable || is_array($thing)) {
return count($thing);
}
return 1;
}
funct;
//access the phar
$p = new Phar('phpDocumentor.phar', FilesystemIterator::CURRENT_AS_FILEINFO | FilesystemIterator::KEY_AS_FILENAME);
//extract the file
$p->extractTo('./', $file, true);
//return here if you want to check the file first
//return;
//change the function
file_put_contents($file,
$newFile = preg_replace(
$oldFunction,
$newFunction,
file_get_contents($file)
)
);
//update the file
$p[$file] = $file;
//done
echo 'Done. Don\'t forget to delete the "vendor" folder extracted from the phar !';

Converting the Inline Json Data to Remote Json File

I used the answer at : YUI 3 -Datatable with Paginator + Query Builder + Sort tried
to for the samples http://jsbin.com/iwijek/10 and http://jsfiddle.net/UwjUt/ which have inline json data. I wanted to parse the remote json file for which I used the .get() as per YUI 3 docs. But bit does not do anything. plz check these examples and help me in parsing the remote json file.
{ var url = "file:///e:/Documents/json-search.txt";
var modelList;
dataSource = new Y.DataSource.Get({ source: url });
// comment
// var modelList = new Y.ModelList();
modelList = new Y.ModelList.Get({
source: url });
modelList.add();
}
json-search.txt
[{
name : 'Joe Bloggs',
company : 'ABC Inc',
state : 'AZ',
cost : 100
},
{
name : 'Jane Mary',
company : 'Bits and Bobs Ltd',
state : 'TX',
cost : 1000
},
{
name : 'Paul Smith',
company : 'PS Clothing PLC',
state : 'TX',
cost :400
},
{
name : 'Jack Jones',
company : 'jackjones.com',
State : 'NY',
cost: 9999
},
{
name : 'Crazy Horse',
company : 'Wacky Places Ltd.',
state : 'MI',
cost : 632
}]
I also tried to pass the datasource to the ModelList
YUI.add(
'datatable-filter',
function(Y) {
/**
Adds support for filtering the table data by API methods
#module datatable
#submodule datatable-filter
#since 3.5.0
**/
var YLang = Y.Lang,
isBoolean = YLang.isBoolean,
isString = YLang.isString,
isArray = YLang.isArray,
isObject = YLang.isObject,
toArray = Y.Array,
sub = YLang.sub;
/**
<pre><code>
var table = new Y.DataTable({
columns: [ 'id', 'username', 'name', 'birthdate' ],
data: [ ... ],
filters: true // this will render a filter input box for every column
});
table.render('#table');
</code></pre>
Setting `filters` to `true` will enable UI filtering for all columns. To enable
UI filtering for certain columns only, set `filters` to an array of column keys,
or just add `filters: true` to the respective column configuration objects.
This uses the default setting of `filters: auto` for the DataTable instance.
<pre><code>
var table = new Y.DataTable({
columns: [
'id',
{ key: 'username', renderFilter: true },
{ key: 'name' },
{ key: 'birthdate', renderFilter: true, filter : "=123", filterFn : customFilterFn }
],
data: [ ... ]
// filters: 'auto' is the default
});
To disable UI filtering for all columns, set `filters` to `false`. This still
permits filtering via the API methods.
filter via api:
var filterBy =
{
username : "=student",
name : "%richard",
birthdate : ">01-01-1975"
}
table.set("filterBy",filterBy);
As new records are inserted into the table's `data` ModelList, they will be checked against the filter to determine if they will be rendered
The current filters are stored in the `filterBy` attribute. Assigning this value at instantiation will automatically filter your data.
Filtering is done by a simple value comparison using '=', '!=', '<', '<=', '>', '>=' on the field value.
If you need custom filtering, add a filter function in the column's `filterFn` property. // TODO...
<pre><code>
function applePiesFilter(a) {
return a.get("type") == 'apple' ? true : false;
}
var table = new Y.DataTable({
columns: [ 'id', 'username', { key: name, filterFn: nameFilter }, 'birthdate' ],
data: [ ... ],
filters: [ 'username', 'name', 'birthdate' ]
});
</code></pre>
See the user guide for more details.
#class DataTable.Filters
#for DataTable
#since 3.5.0
**/
function Filters() {}
Filters.ATTRS = {
// Which columns in the UI should suggest and respond to filtering interaction
// pass an empty array if no UI columns should show filters, but you want the
// table.filter(...) API
/**
Controls which columns can show a filtering input
Acceptable values are:
* "auto" - (default) looks for `renderFilter: true` in the column configurations
* "true" - all columns have a filter field rendered
* "false" - no UI filters are enabled
* {String[]} - array of key names to give filter fields
#attribute filters
#type {String|String[]|Boolean}
#default "auto"
#since 3.5.0
**/
filters: {
value: 'auto',
validator: '_validateFilters'
},
/**
The current filter configuration to maintain in the data.
Accepts column `key` objects with a single property the value of the filter
E.g. `{ username: '%student' }`
E.g. `[{ username : '%student' }, { age : '<40'}]
#attribute filterBy
#type {String|String[]|Object|Object[]}
#since 3.5.0
**/
filterBy: {
validator: '_validateFilterBy'
},
/**
Strings containing language for filtering tooltips.
#attribute strings
#type {Object}
#default (strings for current lang configured in the YUI instance config)
#since 3.5.0
**/
strings: {}
};
Y.mix(Filters.prototype, {
/**
Filter the data in the `data` ModelList and refresh the table with the new
order.
#method filter
#param {String|String[]|Object|Object[]} fields The field(s) to filter by
#param {Object} [payload] Extra `filter` event payload you want to send along
#return {DataTable}
#chainable
#since 3.5.0
**/
filter : function (fields, payload) {
/**
Notifies of an impending filter, either from changing the filter in the UI
header, or from a call to the `filter` method.
The requested filter is available in the `filterBy` property of the event.
The default behavior of this event sets the table's `filterBy` attribute.
#event filter
#param {String|String[]|Object|Object[]} filterBy The requested filter
#preventable _defFilterFn
**/
return this.fire('filter', Y.merge((payload || {}), {
filterBy: fields || this.get('filterBy')
}));
},
/**
Template for the row that will hold the filter inputs
#property FILTERS_HEADER_CELL_TEMPLATE
#type {HTML}
#value
**/
FILTERS_HEADER_ROW_TEMPLATE : '<tr class="{filterRowClassName}" tabindex="0"></tr>',
/**
Template for the row that will hold the filter inputs
#property FILTERS_HEADER_CELL_TEMPLATE
#type {HTML}
#value
//<select><option value="=">=</option><option value="%">%</option><option value="!=">!=</option><option value="!%">!%</option><option value=">">%gt</option><option value=">=">>=</option><option value="<"><</option><option value="<="><=</option></select>
**/
FILTERS_HEADER_CELL_TEMPLATE : '<th class="{className}" tabindex="0" rowspan="1" colspan="1" title="Filter by {colName}">' +
'<div class="{linerClass}" tabindex="0"><input type="text" data-yui3-col-key="{colKey}" class="{inputClass}"/></div></th>',
/**
Template for the row that will doesn't have filter inputs
#property FILTERS_HEADER_CELL_TEMPLATE_NONE
#type {HTML}
#value
**/
FILTERS_HEADER_CELL_TEMPLATE_NONE : '<th class="{className}" tabindex="0" rowspan="1" colspan="1" title="Filtering unavailable on this field"></th>',
//--------------------------------------------------------------------------
// Protected properties and methods
//--------------------------------------------------------------------------
/**
Filters the `data` ModelList based on the new `filterBy` configuration.
#method _afterFilterByChange
#param {EventFacade} e The `filterByChange` event
#protected
#since 3.5.0
**/
_afterFilterByChange: function (e) {
var filters;
// Can't use a setter because it's a chicken and egg problem. The
// columns need to be set up to translate, but columns are initialized
// from Core's initializer. So construction-time assignment would
// fail.
// WHAT DOES THIS MEAN??
this._setFilterBy();
if (this._filterBy.length) {
// build the filter function
this._buildFilterFn();
// get the filtered data
this._filteredData = this.data.filter( { asList : true }, this._filterFn);
} else {
this._filteredData = this.data;
}
// 'hide' the filtered rows
this._hideFilteredData();
},
/**
#description if the row is not in the filtered data hide it, otherwise show it
#method _hideFilteredData
#protected
#since 3.5.0
**/
_hideFilteredData: function () {
var i,len,clientId;
for(i=0, len = this.data.size(); this._filteredData.getById && i < len; ++i) {
clientId = this.data.item(i).get("clientId");
if(this._filteredData.getByClientId(clientId)) {
this.get("contentBox").one("tbody").one("[data-yui3-record=" + clientId + "]").setStyle("display","table-row");
} else {
this.get("contentBox").one("tbody").one("[data-yui3-record=" + clientId + "]").setStyle("display","none");
}
}
},
/**
Applies the filtering logic to the new ModelList if the `newVal` is a new
ModelList.
#method _afterFilterDataChange
#param {EventFacade} e the `dataChange` event
#protected
#since 3.5.0
**/
_afterFilterDataChange: function (e) {
// object values always trigger a change event, but we only want to
// call _initFilterFn if the value passed to the `data` attribute was a
// new ModelList, not a set of new data as an array, or even the same
// ModelList.
if (e.prevVal !== e.newVal || e.newVal.hasOwnProperty('_compare')) {
// this._initFilterFn();
}
},
/**
Checks if any of the fields in the modified record are fields that are
currently being filtered by, and if so, refilters the `data` ModelList.
#method _afterFilterRecordChange
#param {EventFacade} e The Model's `change` event
#protected
#since 3.5.0
**/
_afterFilterRecordChange: function (e) {
var i, len;
for (i = 0, len = this._filterBy.length; i < len; ++i) {
if (e.changed[this._filterBy[i].key]) {
this.data.filter();
break;
}
}
},
/**
Subscribes to state changes that warrant updating the UI, and adds the
click handler for triggering the filter operation from the UI.
#method _bindFilterUI
#protected
#since 3.5.0
**/
_bindFilterUI: function () {
var handles = this._eventHandles;
// 'filterByChange' -> need to update UI
if (!handles.filterAttrs) {
handles.filterAttrs = this.after(
['filtersChange', 'columnsChange'],
Y.bind('_uiSetFilters', this));
}
if (!handles.filterUITrigger && this._theadNode) {
handles.filterUITrigger = this.delegate(['keyup','blur'],
Y.rbind('_onUITriggerFilter', this),
'.' + this.getClassName('filter', 'input'));
}
},
/**
Sets the `filterBy` attribute from the `filter` event's `e.filterBy` value.
#method _defFilterFn
#param {EventFacade} e The `filter` event
#protected
#since 3.5.0
**/
_defFilterFn: function (e) {
this.set.apply(this, ['filterBy', e.filterBy].concat(e.details));
},
/**
Sets up the initial filter state and instance properties. Publishes events
and subscribes to attribute change events to maintain internal state.
#method initializer
#protected
#since 3.5.0
**/
initializer: function () {
var boundParseFilter = Y.bind('_parseFilter', this);
this._parseFilter();
this._setFilterBy();
this._initFilterStrings();
// dataChange : Y.bind('_afterFilterDataChange', this),
//
// filterChange : boundParseFilter
this.after({
'sort' : this._hideFilteredData,
'columnsChange' : boundParseFilter,
'filterByChange' : Y.bind('_afterFilterByChange', this),
'table:renderHeader': Y.bind('_renderFilters', this)});
// this.data.after(this.data.model.NAME + ":change",
// Y.bind('_afterFilterRecordChange', this));
// TODO: this event needs magic, allowing async remote filtering
// this.publish('filter', {
// defaultFn: Y.bind('_defFilterFn', this)
// });
},
/**
Add the filter related strings to the `strings` map.
#method _initFilterStrings
#protected
#since 3.5.0
**/
_initFilterStrings: function () {
// Not a valueFn because other class extensions will want to add to it
this.set('strings', Y.mix((this.get('strings') || {}),
Y.Intl.get('datatable-filter')));
},
/**
#description Fires the `filter` event in response to user changing the UI filters
#method _onUITriggerFilter
#param {DOMEventFacade} e The `mouseout` event
#protected
#since 3.5.0
**/
_onUITriggerFilter: function (e) {
var colKey = e.currentTarget.getAttribute('data-yui3-col-key'),
column = colKey && this.getColumn(colKey),
filterBy = this.get("filterBy") || {},
i, len;
e.halt(); // not doing anything anyway?
if (column) {
filterBy[colKey] = e.currentTarget.get("value");
}
this.set("filterBy",filterBy);
},
/**
#description Build the filter function from the column config, this function is passed to the model list fiter() method
#method _buildFilterFn
#protected
#since 3.5.0
**/
_buildFilterFn: function () {
var i,len,op1,op2, key, filter, filterFn;
filterFn = function(model,index,modelList) {
var key,filter,op1,op2,val,filter,passesFilter = true;
for(i=0,len = this._filterBy.length; i< len && passesFilter; ++i) {
key = this._filterBy[i].key;
filter = this._filterBy[i].filter;
val = model.get(key) || '';
op1 = filter.substr(0,1);
op2 = filter.substr(1,1);
if(op2 == '=') {
switch(op1) {
case '!':
// not equal
if(val.toLowerCase() == filter.substr(2).toLowerCase()) {
passesFilter = false;
}
break;
case '>':
// greater or equal
if(parseInt(val) < parseInt(filter.substr(2))) {
passesFilter = false;
}
break;
case '<':
// less than or equal
if(parseInt(val) > parseInt(filter.substr(2))) {
passesFilter = false;
}
break;
}
} else if (op2 == '%' && op1 =='!') {
// not like
if((val.toLowerCase().indexOf(filter.substr(2).toLowerCase()) > -1)) {
passesFilter = false;
}
break;
} else {
switch(op1) {
case '=':
// equal
if(val.toLowerCase() != filter.substr(1).toLowerCase()) {
passesFilter = false;
}
break;
case '>':
// greater than
if(parseInt(val) <= parseInt(filter.substr(1))) {
passesFilter = false;
}
break;
case '<':
// less than
if(parseInt(val) >= parseInt(filter.substr(1))) {
passesFilter = false;
}
break;
case '%':
// like
if((val.toLowerCase().indexOf(filter.substr(1).toLowerCase()) === -1)) {
passesFilter = false;
}
break;
default:
// consider to be like
if((String(val).toLowerCase().indexOf(String(filter).toLowerCase()) === -1)) {
passesFilter = false;
}
break;
}
}
}
return passesFilter;
};
this._filterFn = Y.bind(filterFn,this);
},
/**
#description Normalizes the possible input values for the `filter` attribute setting up the column config as appropriate
#method _parseFilter
#protected
#since 3.5.0
**/
_parseFilter: function () {
var filters = this.get('filters'),
columns = [],
i, len, col;
col = this._displayColumns.slice();
this._uiFilters = false;
if(filters === 'auto') {
// look for key on columns
col = this._displayColumns.slice();
for(i = 0; i < col.length; i++) {
if(col[i].renderFilter) {
this._uiFilters = true;
}
}
} else if(filters === true) {
// provide UI filters for all cols
col = this._displayColumns.slice();
for(i = 0; i < col.length; i++) {
this._uiFilters = true;
this._displayColumns[i].renderFilter = true;
}
} else if (isArray(filters)) {
// provide UI filters on the specified cols (plural)
for (i = 0, len=filters.length; i < len; ++i) {
if(col = this.getColumn(filters[i])) {
this._uiFilters = true;
col.renderFilter = true;
}
}
} else if (filters) {
// provide UI filter on the specifed 'COL' (singular)
for (i = 0, len = col.length; i < len; ++i) {
if (col[i].key === filters) {
this._uiFilters = true;
this._displayColumns[i].renderFilter = true;
i = len;
}
}
}
},
/**
Initial application of the filters UI.
#method _renderFilters
#protected
#since 3.5.0
**/
_renderFilters: function () {
this._uiSetFilters();
this._bindFilterUI();
},
/**
#description Parses the current `filterBy` attribute and updates the columns
#method _setFilterBy
#protected
#since 3.5.0
**/
_setFilterBy: function () {
var columns = this._displayColumns,
filterBy = this.get('filterBy') || {},
filteredClass = ' ' + this.getClassName('filtered'),
i, len, name, dir, field, column;
this._filterBy = [];
// Purge current filter state from column configs
for (i = 0, len = columns.length; i < len; ++i) {
column = columns[i];
delete columns[i].filter;
if (column.className) {
// TODO: be more thorough
column.className = column.className.replace(filteredClass, '');
}
}
for (key in filterBy) {
if(filterBy[key]!='') {
// Allow filtering of any model field and any column
column = this.getColumn(key) || { _id: key, key: key };
if (column) {
column.filter = filterBy[key];
if (!column.className) {
column.className = '';
}
column.className += filteredClass;
this._filterBy.push(column);
}
}
}
},
/**
Array of column configuration objects of those columns that need UI setup
for user interaction.
#property _filters
#type {Object[]}
#protected
#since 3.5.0
**/
//_filters: null,
/**
Array of column configuration objects for those columns that are currently
being used to filter the data. Fake column objects are used for fields that
are not rendered as columns.
#property _filterBy
#type {Object[]}
#protected
#since 3.5.0
**/
//_filterBy: null,
/**
Replacement `comparator` for the `data` ModelList that defers filtering logic
to the `_compare` method. The deferral is accomplished by returning `this`.
#method _filterComparator
#param {Model} item The record being evaluated for filter position
#return {Model} The record
#protected
#since 3.5.0
**/
_filterComparator: function (item) {
// Defer filtering to ModelList's _compare
return item;
},
/**
Applies the appropriate classes to the `boundingBox` and column headers to
indicate filter state and filterability.
Also currently wraps the header content of filters columns in a `<div>`
liner to give a CSS anchor for filter indicators.
#method _uiSetFilters
#protected
#since 3.5.0
**/
_uiSetFilters: function () {
var columns = this._displayColumns.slice(),
filtersClass = this.getClassName('filters', 'column'),
filtersHidden = this.getClassName("filters","hidden"),
filterRowClass = this.getClassName("filters","row"),
filteredClass = this.getClassName('filtered'),
linerClass = this.getClassName('filter', 'liner'),
i, len, col, node, liner, title, desc;
this.get('boundingBox').toggleClass(
this.getClassName('filters'),
columns.length);
/// NEED TO ADDRESS
if((node = this._theadNode.one("." + filterRowClass))) {
node.remove(true);
}
if(columns.length>0 && this._uiFilters) {
tr = this._theadNode.appendChild(Y.Lang.sub(
this.FILTERS_HEADER_ROW_TEMPLATE, {
filterRowClassName: filterRowClass }));
for (i = 0, len = columns.length; i < len; ++i) {
if(columns[i].renderFilter) {
tr.append(Y.Lang.sub(
this.FILTERS_HEADER_CELL_TEMPLATE, {
className: this.getClassName("filter","cell"),
colKey : columns[i].key,
colName : columns[i].label || columns[i].key,
inputClass : this.getClassName("filter","input"),
linerClass: linerClass
}));
} else {
tr.append(Y.Lang.sub(
this.FILTERS_HEADER_CELL_TEMPLATE_NONE, {
className: this.getClassName("no-filter")
}));
}
}
}
},
/**
Allows values `true`, `false`, "auto", or arrays of column names through.
#method _validateFilters
#param {Any} val The input value to `set("filters", VAL)`
#return {Boolean}
#protected
#since 3.5.0
**/
_validateFilters: function (val) {
return val === 'auto' || isBoolean(val) || isArray(val);
},
/**
Allows strings, arrays of strings, objects, or arrays of objects.
#method _validateFilterBy
#param {String|String[]|Object|Object[]} val The new `filterBy` value
#return {Boolean}
#protected
#since 3.5.0
**/
_validateFilterBy: function (val) {
return val;
return val === null ||
isString(val) ||
isObject(val, true) ||
(isArray(val) && (isString(val[0]) || isObject(val, true)));
}
}, true);
Y.DataTable.Filters = Filters;
Y.Base.mix(Y.DataTable, [Filters]);
},"0.1", {
requires : []});
YUI().use('datatable-sort','datatable-filter',function(Y) {
// comment
//var modelList = new Y.ModelList();
var url = "file:///e:/Documents/json-search.txt";
var modelList, datasource;
modelList = new Y.ModelList();
datasource = Y.DataSource.IO({ source: "file:///e:/Documents/json-search.txt" });
modelList.plug(Y.Plugin.ModelListDataSource, {
source : datasource, });
datasource.sendRequest();
var dataTable = new Y.DataTable (
{
columns : [ {key:"name",label:"Person",renderFilter:true,filter:"Joe"},"company",{key:"state",renderFilter:true},{key:"cost",renderFilter:true}],
data : modelList, sortable : true, filters : 'auto'
}).render("#table");
modelList.item(1).set("id",102);
Y.one("#showhidefilters").on("click",function(e) {e.halt();Y.one("#table").one(".yui3-datatable-filters-row").toggleClass("yui3-datatable-filters-hidden");});
});

php mySQL Reliable way to check if a row matches a object class

I'm looking for a reliable way to check to see if a database entry matches an equivalent object class in php.
My current method is unreliable, I was hoping someone could supply a better solution.
My current solution seems to work most of the time, but out of around 600 entries, Ill randomly return about 5 entry's that are false positives.
Here is a simplified object class Im using
class MemberData
{
public $AccountID;
public $AccountName;
public $Website;
}
I then use reflection to loop through each property in the class and build my query string in the form of :
SELECT 1 WHERE `Property1` = value1 AND `Property2` = value2 AND `Property3` = value3
However like i mentioned, my code only works most of the time, and I cant pin down a common link on why Im getting false positives. It appears random.
Below is my full function.
//Pass in a member class and see if there is a matching database entry
function SqlDoRowValuesMatch($memberData)
{
//declare global vars into this scope
global $host, $user, $password, $dbname, $tableName;
//initiate the connection using mysqli
$databaseConnection = new mysqli($host, $user, $password, $dbname);
if($databaseConnection->connect_errno > 0)
{
die('Unable to connect to database [' . $databaseConnection->connect_error . ']');
}
//Get all the properties in the MemberData Class
//Using Reflection
$reflect = new ReflectionClass($memberData);
$props = $reflect->getProperties(ReflectionProperty::IS_PUBLIC);
//Build the query string
$sql = "SELECT 1 FROM `".$tableName."` WHERE ";
foreach($props as $prop)
{
if(!is_null($prop->getValue($memberData)))
{
$sql = $sql.$prop->getName()."=".addSingleQuotes(addslashes($prop->getValue($memberData)))." AND ";
}
}
//Cut Trailing operator
$sql = rtrim($sql, " AND ");
if(!$result = $databaseConnection->query($sql))
{
die('There was an error creating [' . $databaseConnection->error . ']');
}
$databaseConnection->close();
//Check for a value of 1 to indicate that a match was found
$rowsMatch = 0;
while($row = $result->fetch_assoc())
{
foreach($row as $key => $value)
{
if($value == 1)
{
$rowsMatch = 1;
break;
}
}
}
return $rowsMatch; //0 = false, 1 = true
}

Hide mySQL error from invalid URL

I have a site with 300 articles stored in a mySQL database with the URL format of www.site.com/article1.html.
Most invalid URLs redirect succesfully to the main site. For example, www.site.com/article301 redirects to www.site.com, which is what I want.
But www.site.com/article301.html does not redirect anywhere. Instead it loads a blank article template and the following error at the top of the page:
Warning: mysql_num_rows(): supplied argument is not a valid MySQL result resource in /home//public_html/site.com/functions.php on line 26
Line 26 and down reads
if(mysql_num_rows($result)>0) {
$row=mysql_fetch_array($result);
if(ENABLE_REWRITE == 1) $path=' » '.$row['name'].''.$path;
if(ENABLE_REWRITE == 0) $path=' » '.$row['name'].''.$path;
if($row['parent']==0) $f=1;
else $id=$row['parent'];
} else {
return ' - ';
}
}
return $path;
}
Any ideas how to fix this?
Here's the full code, as requested by King Skippus
<?php
/*function get_folders_path($id) {
$f=0;
$path='';
while($f==0)
{
$result=mysql_query("SELECT name, parent FROM categories WHERE id=$id");
if(mysql_num_rows($result)>0) {
$row=mysql_fetch_array($result);
$path=' » '.$row['name'].$path;
if($row['parent']==0) $f=1;
else $id=$row['parent'];
} else {
return ' - ';
}
}
return $path;
}*/
function get_folders_path($id) {
$f=0;
$path='';
while($f==0)
{
$result=mysql_query("SELECT * FROM categories WHERE id=$id");
if($result !== FALSE && mysql_num_rows($result)>0) {
$row=mysql_fetch_array($result);
if(ENABLE_REWRITE == 1) $path=' » '.$row['name'].''.$path;
if(ENABLE_REWRITE == 0) $path=' » '.$row['name'].''.$path;
if($row['parent']==0) $f=1;
else $id=$row['parent'];
} else {
return ' - ';
}
}
return $path;
}
function get_categories_tree($id) {
static $categs = array ();
static $level=0;
$level++;
$result=mysql_query("SELECT * FROM categories WHERE parent=$id");
while($row=mysql_fetch_array($result)) {
$categs[$row['id']][0] = $row['id'];
$categs[$row['id']][1] = '/'.$row['nameurl'];
$categs[$row['id']][2] = str_repeat(' ', $level-1);
$categs[$row['id']][3] = $row['name'];
get_categories_tree($row['id']);
}
$level--;
return $categs;
}
function get_cats($id) {
$categs = array ();
$result=mysql_query("SELECT * FROM categories WHERE parent=$id");
while($row=mysql_fetch_array($result)) {
$categs[$row['id']][0] = $row['id'];
$categs[$row['id']][1] = '/'.$row['nameurl'];
// $categs[$row['id']][2] = str_repeat(' ', $level-1);
$categs[$row['id']][3] = $row['name'];
}
return $categs;
}
/*function login() {
if (!isset($_SERVER['PHP_AUTH_USER'])) {
header('WWW-Authenticate: Basic realm="My Realm"');
header('HTTP/1.0 401 Unauthorized');
return false;
} else {
$result=mysql_query("SELECT * FROM users WHERE login='{$_SERVER['PHP_AUTH_USER']}' AND password='{$_SERVER['PHP_AUTH_PW']}'");
if(mysql_num_rows($result)>0) return true;
else {
header('WWW-Authenticate: Basic realm="My Realm"');
header('HTTP/1.0 401 Unauthorized');
return false;
}
}
}*/
function login() {
if (!isset($_SESSION['AUTH_USER']) || !isset($_SESSION['AUTH_PASS'])) return false;
else {
$result=mysql_query("SELECT * FROM users WHERE login='{$_SESSION['AUTH_USER']}' AND password='{$_SESSION['AUTH_PASS']}'");
if(mysql_num_rows($result)>0) return true;
else return false;
}
}
function get_categories($id) {
static $categs = array ("0" => "[Top]");
static $level=0;
$level++;
$result=mysql_query("SELECT * FROM categories WHERE parent=$id");
while($row=mysql_fetch_array($result)) {
$categs[$row['id']] = str_repeat('| ', $level-1).'|___'.$row['name'];
get_categories($row['id']);
}
$level--;
return $categs;
}
function get_parent_name($id) {
if($id!=0) {
$result=mysql_query("SELECT name FROM categories WHERE id=$id");
if(mysql_num_rows($result)>0) {
$row=mysql_fetch_array($result);
return $row['name'];
}
else return '-';
}
else return 'Top';
}
function getcatname($id, $table)
{
$r=mysql_query("SELECT title FROM $table WHERE id='$id'");
if(mysql_num_rows($r)>0) {
$row=mysql_fetch_array($r);
return $row['title'];
}
else
return "-";
}
?>
Probably your query failed, and you have no error handling. Your basic bare-bones query sequence should be:
$result = mysql_query($sql) or die(mysql_error());
^^^^^^^^^^^^^^^^^^^^^^
If you assume the query succeeded and blindly use $result later, you tend to get the type of errors you do, as mysql_query will return a boolean FALSE when something goes boom. That FALSE is not a valid statement handle, so the subsequent num_rows/fetch calls will also go boom.
Never assume a query has succeeded. Even if your sql syntax is 100% perfect, there's far too many other reasons for failure to NOT check.
Try replacing
if(mysql_num_rows($result)>0) {
with
if($result === FALSE) {
header('Location: http://www.example.com/');
}
else if (mysql_num_rows($result)>0) {
// Query was valid, but no rows returned. Take appropriate action.
}
EDIT
For troubleshooting purposes, what does it display if you change the function to this instead? Please be aware that this will intentionally break your site, but it will provide data that is useful for troubleshooting.
function get_folders_path($id) {
$f=0;
$path='';
while($f==0)
{
$result=mysql_query("SELECT * FROM categories WHERE id=$id");
die(sprintf("Value of id: %s, MySQL Error: %s",
var_dump($id, true), var_dump(mysql_error($result), true)));
// Leave the rest of your function as-is, just insert the line above.