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

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)

Related

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

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

Mysql Clone user account from database

I have a database with aproximately 200 tables. I want to clone a certain user-account in this database. Is this possible in mysql?
With cloning I mean to create a new user with the same 'settings' as the user with id 14.
A quick google search reveals that you in fact can do this. There is a utility called " "mysql user clone", that lets you surprisingly clone a user for mysql.
If you check out the manual I'm sure it provides you with great tips about how to use it, for instance, this quote:
EXAMPLES
To clone joe as sam and sally with passwords and logging in as root on the local machine, use this command:
$ mysqluserclone --source=root#localhost \
--destination=root#localhost \
joe#localhost sam:secret1#localhost sally:secret2#localhost
# Source on localhost: ... connected.
# Destination on localhost: ... connected.
# Cloning 2 users...
# Cloning joe#localhost to user sam:secret1#localhost
# Cloning joe#localhost to user sally:secret2#localhost
# ...done.
since it appears #Nanne's approach, mysqluserclone is EOL / not supported by Oracle, i wrote a similar utility in PHP, usage:
<?php
$db = new \PDO("mysql:host={$db_creds->dbhost};dbname={$db_creds->dbname};charset=utf8mb4;port=" . $db_creds->dbport, $db_creds->superuser_user, $db_creds->superuser_pass, array(
\PDO::ATTR_EMULATE_PREPARES => false,
\PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION,
\PDO::ATTR_DEFAULT_FETCH_MODE => \PDO::FETCH_ASSOC
));
Mysqluserclone::clone_account($db, "original username", "cloned username");
and this part of the code may be of particular interest:
if (0) {
echo "the following SQLs will clone this account:\n";
echo implode("\n\n", $sqls_for_cloning) . "\n\n";
die();
}
<?php
class Mysqluserclone{
private function __construct(){
// by making this private, we ensure nobody try to instantiate us.
}
public static function clone_account(\PDO $db_connected_as_superuser, string $original_name, string $clone_name): void
{
$db = $db_connected_as_superuser;
$sqls_for_cloning = [];
$sql = "SELECT COUNT(*) FROM mysql.user WHERE User = " . $db->quote($clone_name);
if (0 !== $db->query($sql)->fetch(\PDO::FETCH_NUM)[0]) {
throw new \InvalidArgumentException("clone name already exists!");
}
$sql = "SELECT * FROM mysql.user WHERE User = " . $db->quote($original_name);
$current_user_one_for_each_host = $db->query($sql)->fetchAll(\PDO::FETCH_ASSOC);
foreach ($current_user_one_for_each_host as $user_record) {
$user_record["User"] = $clone_name;
$sql = "INSERT INTO mysql.user SET \n";
foreach ($user_record as $name => $val) {
$sql .= self::mysql_quote_identifier($name) . " = " . self::mysql_quote_better($db, $val) . ",\n";
}
if (! empty($user_record)) {
$sql = substr($sql, 0, - strlen(",\n"));
}
$sql .= ";";
$sqls_for_cloning[] = $sql;
$sqls_for_cloning[] = "FLUSH PRIVILEGES;"; // YES this is required, otherwise you might get "grant not allowed to create accounts" errors
$grants_raw_sql = 'SHOW GRANTS FOR ' . $db->quote($original_name) . '#' . $db->quote($user_record['Host']) . ";";
try {
$grants_raw = $db->query($grants_raw_sql)->fetchAll(\PDO::FETCH_NUM);
} catch (\Throwable $ex) {
// somehow an empty grant table is a mysql error, not an empty rowset.. ignore it.
$grants_raw = [];
}
$grants_raw = array_map(function (array $arr): string {
if (count($arr) !== 1) {
throw new \LogicException("mysql layout for SHOW GRANTS has changed? investigate");
}
return $arr[0];
}, $grants_raw);
$original_name_as_identifier = self::mysql_quote_identifier($original_name);
$clone_name_as_identifier = self::mysql_quote_identifier($clone_name);
foreach ($grants_raw as $grant) {
if (false === strpos($grant, $original_name_as_identifier)) {
throw new \LogicException("original grant without original name as identifier? investigate");
}
$grant = self::str_replace_last($original_name_as_identifier, $clone_name_as_identifier, $grant);
$grant .= ";";
$sqls_for_cloning[] = $grant;
}
}
if (! empty($sqls_for_cloning)) {
$sqls_for_cloning[] = "FLUSH PRIVILEGES;";
}
if (0) {
echo "the following SQLs will clone this account:\n";
echo implode("\n\n", $sqls_for_cloning) . "\n\n";
die();
}
foreach ($sqls_for_cloning as $clone_sql) {
$db->exec($clone_sql);
}
}
private static function mysql_quote_identifier(string $identifier): string
{
return '`' . strtr($identifier, [
'`' => '``'
]) . '`';
}
private static function mysql_quote_better(\PDO $db, $value): string
{
if (is_null($value)) {
return "NULL";
}
if (is_int($value)) {
return (string) $value;
}
if (is_float($value)) {
return number_format($value, 10, '.', '');
}
if (is_bool($value)) {
return ($value ? "1" : "0");
}
return $db->quote($value);
}
private static function str_replace_last(string $search, string $replace, string $subject): string
{
$pos = strrpos($subject, $search);
if ($pos !== false) {
$subject = substr_replace($subject, $replace, $pos, strlen($search));
}
return $subject;
}
}

Amazon Product Ads, is there an API to search for Categories?

I'm building a module that will help seller put their products catalogue in the Amazon Product Ads service. For that, I need to make a mapping between the client's category and the Amazon Product Ads categories.
Problem is, I can't find an API that will help me search for Categories, or a file containing all the existing categories for Amazon Product Ads.
I found that link http://docs.aws.amazon.com/AWSECommerceService/latest/DG/BrowseNodeIDs.html, that may be a start, but based on their API, it's not possible to search by text (like "Apparel") but by NodeId, which is not what I'm looking for :/
Can anyone of you help me please?
Thank you for your help :)
You have to use Browse Node Id of parent categories and bases on that you can search for sub categories.
Create a file named amazon_api_class.php
<?php
require_once 'aws_signed_request.php';
class AmazonProductAPI
{
/**
* Your Amazon Access Key Id
* #access private
* #var string
*/
private $public_key = "";
/**
* Your Amazon Secret Access Key
* #access private
* #var string
*/
private $private_key = "";
private $media_type = "";
private $region = "";
private $out_file_fp = "";
public function __construct($public, $private, $region) {
$this->public_key = $public;
$this->private_key = $private;
$this->region = $region;
}
public function getNode($node)
{
$parameters = array("Operation" => "BrowseNodeLookup",
"BrowseNodeId" => $node,
"ResponseGroup" => "BrowseNodeInfo");
$xml_response = aws_signed_request($parameters,
$this->public_key,
$this->private_key,
$this->region);
return ($xml_response);
}
public function setMedia($media, $file = "") {
$media_type = array("display", "csv");
if(!in_array($media,$media_type)) {
throw new Exception("Invalid Media Type");
exit();
}
$this->media_type = $media;
if($media == "csv") {
$this->out_file_fp = fopen($file,'a+');
}
}
private function writeOut($level, $name, $id, $parent) {
if($this->media_type == "display") {
$spaces = str_repeat( ' ', ( $level * 6 ) );
echo $spaces . $parent . ' : ' . $name . ' : ' . $id . "\n";
} elseif ($this->media_type == "csv") {
$csv_line = '"' . $parent . '","' . $name . '","' . $id . '"' . "\n";
fputs($this->out_file_fp, $csv_line);
} else {
throw new Exception("Invalid Media Type");
exit();
}
}
public function getBrowseNodes($nodeValue, $level = 0)
{
try {
$result = $this->getNode($nodeValue);
}
catch(Exception $e) {
echo $e->getMessage();
}
if(!isset($result->BrowseNodes->BrowseNode->Children->BrowseNode)) return;
if(count($result->BrowseNodes->BrowseNode->Children->BrowseNode) > 0) {
foreach($result->BrowseNodes->BrowseNode->Children->BrowseNode as $node) {
$this->writeOut($level, $node->Name,
$node->BrowseNodeId,
$result->BrowseNodes->BrowseNode->Name);
$this->getBrowseNodes($node->BrowseNodeId, $level+1);
}
} else {
return;
}
}
public function getNodeName($nodeValue)
{
try {
$result = $this->getNode($nodeValue);
}
catch(Exception $e) {
echo $e->getMessage();
}
if(!isset($result->BrowseNodes->BrowseNode->Name)) return;
return (string)$result->BrowseNodes->BrowseNode->Name;
}
public function getParentNode($nodeValue)
{
try {
$result = $this->getNode($nodeValue);
}
catch(Exception $e) {
echo $e->getMessage();
}
if(!isset($result->BrowseNodes->BrowseNode->Ancestors->BrowseNode->BrowseNodeId)) return;
$parent_node = array("id" => (string)$result->BrowseNodes->BrowseNode->Ancestors->BrowseNode->BrowseNodeId,
"name" => (string)$result->BrowseNodes->BrowseNode->Ancestors->BrowseNode->Name);
return $parent_node;
}}?>
Create file named as aws_signed_request.php
<?php
function aws_signed_request($params,$public_key,$private_key,$region)
{
$method = "GET";
$host = "ecs.amazonaws.".$region; // must be in small case
$uri = "/onca/xml";
$params["Service"] = "AWSECommerceService";
$params["AWSAccessKeyId"] = $public_key;
$params["AssociateTag"] = 'YOUR-ASSOCIATES-ID-HERE';
$params["Timestamp"] = gmdate("Y-m-d\TH:i:s\Z");
$params["Version"] = "2009-03-31";
/* The params need to be sorted by the key, as Amazon does this at
their end and then generates the hash of the same. If the params
are not in order then the generated hash will be different thus
failing the authetication process.
*/
ksort($params);
$canonicalized_query = array();
foreach ($params as $param=>$value)
{
$param = str_replace("%7E", "~", rawurlencode($param));
$value = str_replace("%7E", "~", rawurlencode($value));
$canonicalized_query[] = $param."=".$value;
}
$canonicalized_query = implode("&", $canonicalized_query);
$string_to_sign = $method."\n".$host."\n".$uri."\n".$canonicalized_query;
/* calculate the signature using HMAC with SHA256 and base64-encoding.
The 'hash_hmac' function is only available from PHP 5 >= 5.1.2.
*/
$signature = base64_encode(hash_hmac("sha256", $string_to_sign, $private_key, True));
/* encode the signature for the request */
$signature = str_replace("%7E", "~", rawurlencode($signature));
/* create request */
$request = "http://".$host.$uri."?".$canonicalized_query."&Signature=".$signature;
/* I prefer using CURL */
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,$request);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, 15);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
$xml_response = curl_exec($ch);
if ($xml_response === False)
{
return False;
}
else
{
/* parse XML */
$parsed_xml = #simplexml_load_string($xml_response);
return ($parsed_xml === False) ? False : $parsed_xml;
}
}
?>
Create file named as index.php
<?php
/* Example usage of the Amazon Product Advertising API */
include("amazon_api_class.php");
$public_key = "YOUR-AMAZON-PUBLIC-KEY";
$private_key = "YOUR-AMAZON-SECRET-KEY";
$region = "com"; // or "CA" or "DE" etc.
$obj = new AmazonProductAPI($public_key, $private_key, $region);
$obj->setMedia("display");
$obj->getBrowseNodes("1036592"); //Apparel US store
?>
Dont forget to update your public and private key in index.php

JOIN on a subquery with Zend Framework 2 TableGateway

I'm trying to do a query with Zend Framework 2 where I have a SELECT inside a JOIN statement. So far, here's what I've tried, but injecting the SELECT object into the first parameter of join() doesn't seem to be working. I've resorted to such an approach since I need to order the results first before doing any grouping. Any ideas on how to get it working?
public function getSearchKeyword($keyword, $limit)
{
$select = $this->keywords->getSql()->select();
$subquery = $this->pages->getSql()->select();
$subWhere = new \Zend\Db\Sql\Where();
$subWhere->equalTo('delete_flag', 'n')
->equalTo('published_flag', 'y');
$subquery->where($subWhere);
$where = new \Zend\Db\Sql\Where();
$where->like('keyword', '%' . $keyword . '%')
->equalTo('delete_flag', 'n');
$select->columns(array('display' => 'keyword', 'url'))
->join(array('sub' => $subquery), 'sub.page_id = keywords.page_id', array())
->where($where)
->group(array('keywords.page_id', 'keywords.keyword'))
->order(array('rank', 'keyword'))
->limit($limit);
$row = $this->tableGateway->selectWith($select);
return $row;
}
The query I'm trying to write is below:
SELECT keywords.keyword AS display, keywords.url
FROM keywords
INNER JOIN
(
SELECT * FROM pages WHERE published_flag = 'y' AND delete_flag = 'n' ORDER BY page_id DESC
) pages
ON pages.page_id = keywords.page_id
WHERE published_flag = 'y'
AND delete_flag = 'n'
AND keywords.keyword LIKE '%?%'
GROUP BY display, page_id;
I was working around the same problem and did not found a standard way to solve it. So I got a working but not zf2 standard one
Create a small interface to mannage Db conections
Implements it as a small class to get a connection PDO object to
your database
execute your arbitrary querys
Code sample
// Filename: /module/MyTools/src/MyTools/Service/DbModelServiceInterface.php
namespace MyTools\Service;
interface DbModelServiceInterface
{
/**
* Will return the result of querying the curret database
*
* #param type $query
* #result mixed
*/
public function dbQuery($query);
/**
* Will return a connection object that links to curret database
*
* #result mixed
*/
public function getConnection();
}
The class implementing the interface. It creates and offers a PDO connection. Note: It needs extra code to close conns and to perfeorm security adm...
It test it and is completely functional.
code:
// Filename: /module/MyTools/src/MyTools/Service/DbModelServiceMySql.php
namespace MyTools\Service;
use MyTools\Service\DbModelServiceInterface;
use PDO;
class DbModelServiceMySql implements DbModelServiceInterface
{
protected $driverConfig;
protected $connection;
protected $isconnected = FALSE;
protected $dbname = '';
/**
* Creates a connection to main database
*/
public function __construct()
{
$driverConfig = self::getDriverDef();
$this->driverConfig = $driverConfig; // new PDO($driverConfig['dsn'], $driverConfig['username'], $driverConfig['password']);
$this->_connect();
}
protected function _connect(){
$dsn = (isset($this->driverConfig['dsn'])) ? $this->driverConfig['dsn'] : '';
$username = (isset($this->driverConfig['username'])) ? $this->driverConfig['username'] : '';
$password = (isset($this->driverConfig['password'])) ? $this->driverConfig['password'] : '';
if( ($dsn) && ($username) && ($password)){
$options = [PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8', ];
try {
$this->connection = new PDO($dsn, $username, $password, $options);
$this->isconnected = TRUE;
$this->_setdbname($dsn);
} catch (Exception $ex) {
throw new RuntimeException('YOUR ERROR MESSAGE.');
}
}
return $this->isconnected;
}
protected function _setdbname($dsn){
if($dsn){
$chunks = explode(';', ''.$dsn);
foreach($chunks as $chunk){
if(strpos('***'.$chunk, 'dbname') > 2){
$nombre = explode('=', $chunk);
$this->dbname = $nombre[1];
break;
}
}
}
}
/**
* {#inheritDoc}
*/
public function dbQuery($query) {
if($this->connection){
$resultset = $this->connection->query($query);
if($resultset){
return $resultset->fetchAll(PDO::FETCH_ASSOC);
}else{
return ['Error' => 'YOUR CUSTOM ERROR MESSAGE.'];
}
}else{
return ['Error' => 'OTHER CUSTOM ERROR MESSAGE'];
}
}
public static function getDriverDef()
{
$autoloadDir = __DIR__ . '../../../../../../config/autoload/';
$credentialsdb = include $autoloadDir . 'local.php';
$globaldb = include $autoloadDir . 'global.php';
$def = (isset($globaldb['db'])) ? $globaldb['db'] : array();
$credentials = (isset($credentialsdb['db'])) ? $credentialsdb['db'] : $credentialsdb;
return array_merge($def, $credentials);
}
/**
* {#inheritDoc}
*/
public function getConnection() {
if($this->connection){
return $this->connection;
}else{
return 'Error: YOUR CUSTOM ERROR MESSAGE';
}
}
/**
* {#inheritDoc}
*/
public function getDbName(){
return $this->dbname;
}
}
Now you have a class you can instantiate elsewhere to perform the querys you need.
use:
code:
$myQuery = 'the very very complex query you need to execute'
$myDbConn = new MyTools\Service\DbModelServiceMySql();
$result = $myDbConn->dbQuery($myQuery);
If success you got a resulset array of pairs columnName => value
You can try this one.
$select->columns(array('display' => 'keyword', 'url'))
->join(array('sub' => 'pages'), 'sub.page_id = keywords.page_id',
array(), $select::JOIN_INNER)
->where($where)
->group(array('keywords.page_id', 'keywords.keyword'))
->order(array('rank', 'keyword'))
->limit($limit);
In your code, you are getting all keywords which page_id's is in sub page_id where delete_flag = 'n' and published_flag = 'y'.
join(..., 'sub.page_id = keywords.page_id', array())
When you don't need any columns of pages table, you can use IN instead of JOIN.
For example when you need to know which keywords are in which pages, you should use JOIN, but when you need to know which keyboards are in any pages, you can use IN statement.
Anyway :
There is no standard way in ZF2 but you can try following code.
public function getSearchKeyword($keyword, $limit)
{
$select = $this->keywords->getSql()->select();
$subquery = $this->pages->getSql()->select();
$subWhere = new \Zend\Db\Sql\Where();
$subWhere->equalTo('delete_flag', 'n')
->equalTo('published_flag', 'y');
$subquery->columns(array('page_id'))
->where($subWhere);
$where = new \Zend\Db\Sql\Where();
$where->like('keyword', '%' . $keyword . '%')
->equalTo('delete_flag', 'n')
->in('keywords.page_id', $subquery);
$select->columns(array('display' => 'keyword', 'url'))
->where($where)
->group(array('keywords.page_id', 'keywords.keyword'))
->order(array('rank', 'keyword'))
->limit($limit);
$row = $this->tableGateway->selectWith($select);
return $row;
}
I've faced a similar issue. Since the FROM table and Subquery's FROM table were different i got an error.
My workaround was to extract the SQL and create a statement.
$sql = $select->getSqlString(new \Zend\Db\Adapter\Platform\Mysql());
$stmt = $this->getAdapter()->createStatement($sql);
$stmt->prepare($sql);
$result = $stmt->execute();
$resultSet = new ResultSet(); \\ Class Zend\Db\ResultSet\ResultSet
$resultSet->initialize($result);

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.