For some odd reason im unable to retrieve group memebers from domain users or any group for that batter.
Base DN is set to dc=domain,dc=com Ive hits block here. When I use the test tool im able to authenticate [NOTICE] Authentication successfull for "rpimentel#domain.com"
Something is missing. Something simple, that im over looking. What could it be?
// Extend the ADIntegrationPlugin class
class BulkImportADIntegrationPlugin extends ADIntegrationPlugin {
/**
* Output formatted debug informations
*
* #param integer level
* #param string $notice
*/
protected function _log($level = 0, $info = '') {
if ($level <= $this->_loglevel) {
switch ($level) {
case ADI_LOG_DEBUG:
$class = 'debug';
$type = '[DEBUG] ';
break;
case ADI_LOG_INFO:
$class = 'info';
$type = '[INFO] ';
break;
case ADI_LOG_NOTICE:
$class = 'notice';
$type = '[NOTICE] ';
break;
case ADI_LOG_WARN:
$class = 'warn';
$type = '[WARN] ';
break;
case ADI_LOG_ERROR:
$class = 'error';
$type = '[ERROR] ';
break;
case ADI_LOG_FATAL:
$class = 'fatal';
$type = '[FATAL] ';
break;
default:
$class = '';
$type = '';
}
$output = '<span class="'.$class.'">'.$type;
$output .= str_replace("\n","<br /> ",$info).'</span><br />';
echo $output;
if (WP_DEBUG) {
if ($fh = #fopen($this->_logfile,'a+')) {
fwrite($fh,$type . str_replace("\n","\n ",$info) . "\n");
fclose($fh);
}
}
}
}
/**
* Do Bulk Import
*
* #param string $authcode
* #return bool true on success, false on error
*/
public function bulkimport($authcode)
{
global $wp_version;
global $wpdb;
$this->setLogFile(dirname(__FILE__).'/import.log');
$this->_log(ADI_LOG_INFO,"-------------------------------------\n".
"START OF BULK IMPORT\n".
date('Y-m-d / H:i:s')."\n".
"-------------------------------------\n");
$time = time();
$all_users = array();
// Is bulk import enabled?
if (!$this->_bulkimport_enabled) {
$this->_log(ADI_LOG_INFO,'Bulk Import is disabled.');
return false;
}
// DO we have the correct Auth Code?
if ($this->_bulkimport_authcode !== $authcode) {
$this->_log(ADI_LOG_ERROR,'Wrong Auth Code.');
return false;
}
$ad_password = $this->_decrypt($this->_bulkimport_pwd);
// Log informations
$this->_log(ADI_LOG_INFO,"Options for adLDAP connection:\n".
"- base_dn: $this->_base_dn\n".
"- domain_controllers: $this->_domain_controllers\n".
"- ad_username: $this->_bulkimport_user\n".
"- ad_password: **not shown**\n".
"- ad_port: $this->_port\n".
"- use_tls: ".(int) $this->_use_tls."\n".
"- network timeout: ". $this->_network_timeout);
// Connect to Active Directory
try {
$this->_adldap = #new adLDAP(array(
"base_dn" => $this->_base_dn,
"domain_controllers" => explode(';', $this->_domain_controllers),
"ad_username" => $this->_bulkimport_user, // Bulk Import User
"ad_password" => $ad_password, // password
"ad_port" => $this->_port, // AD port
"use_tls" => $this->_use_tls, // secure?
"network_timeout" => $this->_network_timeout // network timeout
));
} catch (Exception $e) {
$this->_log(ADI_LOG_ERROR,'adLDAP exception: ' . $e->getMessage());
return false;
}
$this->_log(ADI_LOG_NOTICE,'adLDAP object created.');
$this->_log(ADI_LOG_INFO,'Domain Controller: ' . $this->_adldap->get_last_used_dc());
// Let's give us some more time (60 minutes)
$max_execution_time = ini_get('max_execution_time');
if ($max_execution_time < 3600) {
ini_set('max_execution_time', 3600);
}
if (ini_get('max_execution_time') < 3600) {
$this->_log(ADI_LOG_ERROR,'Can not increase PHP configuration option "max_execution_time".');
return false;
}
// get all users of the chosen security groups from
$groups = explode(";",$this->_bulkimport_security_groups);
if (count($groups) < 1) {
$this->_log(ADI_LOG_WARN,'No security group.');
return false;
}
foreach ($groups AS $group) {
// get all members of group
$group = trim($group);
if ($group != '') {
// do we have a groupid?
if (($pos = stripos($group,'id:')) !== false) {
$pgid = substr($group,$pos+3);
$members = $this->_adldap->group_members_by_primarygroupid($pgid, true);
} else {
$members = $this->_adldap->group_members($group, true);
}
if ($members) {
$this->_log(ADI_LOG_INFO,count($members).' Members of group "'.$group.'".');
$this->_log(ADI_LOG_DEBUG,'Members of group "'.$group.'": ' . implode(', ',$members));
foreach ($members AS $user) {
$all_users[strtolower($user)] = $user;
}
} else {
$this->_log(ADI_LOG_ERROR,'Error retrieving group members for group "'.$group.'".');
}
} else {
$this->_log(ADI_LOG_WARN,'No group. Nothing to do.');
}
}
// Adding all local users with non empty entry adi_samaccountname in usermeta
$blogusers=$wpdb->get_results(
'
SELECT
users.user_login
FROM
'. $wpdb->users . ' users
INNER JOIN
' . $wpdb->usermeta ." meta ON meta.user_id = users.ID
where
meta.meta_key = 'adi_samaccountname'
AND
meta.meta_value IS NOT NULL
AND
meta.meta_value <> ''
AND
users.ID <> 1
"
);
if (is_array($blogusers)) {
foreach ($blogusers AS $user) {
$all_users[strtolower($user->user_login)] = $user->user_login;
}
}
$elapsed_time = time() - $time;
$this->_log(ADI_LOG_INFO,'Number of users to import/update: '.count($all_users).' (list generated in '. $elapsed_time .' seconds)');
if (version_compare($wp_version, '3.1', '<')) {
require_once(ABSPATH . WPINC . DIRECTORY_SEPARATOR . 'registration.php');
}
// import all relevant users
$added_users = 0;
$updated_users = 0;
foreach ($all_users AS $username) {
$ad_username = $username;
// getting user data
//$user = get_userdatabylogin($username); // deprecated
$user = get_user_by('login', $username);
// role
$user_role = $this->_get_user_role_equiv($ad_username); // important: use $ad_username not $username
// userinfo from AD
$this->_log(ADI_LOG_DEBUG, 'ATTRIBUTES TO LOAD: '.print_r($this->_all_user_attributes, true));
$userinfo = $this->_adldap->user_info($ad_username, $this->_all_user_attributes);
$userinfo = $userinfo[0];
$this->_log(ADI_LOG_DEBUG,"USERINFO[0]: \n".print_r($userinfo,true));
if (empty($userinfo)) {
$this->_log(ADI_LOG_INFO,'User "' . $ad_username . '" not found in Active Directory.');
if (isset($user->ID) && ($this->_disable_users)) {
$this->_log(ADI_LOG_WARN,'User "' . $username . '" disabled.');
$this->_disable_user($user->ID, sprintf(__('User "%s" not found in Active Directory.', 'ad-integration'), $username));
}
} else {
// Only user accounts (UF_NORMAL_ACCOUNT is set and other account flags are unset)
if (($userinfo["useraccountcontrol"][0] & (UF_NORMAL_ACCOUNT | ADI_NO_UF_NORMAL_ACOUNT)) == UF_NORMAL_ACCOUNT) {
//&& (($userinfo["useraccountcontrol"][0] & ADI_NO_UF_NORMAL_ACOUNT) == 0)) {
// users with flag UF_SMARTCARD_REQUIRED have no password so they can not logon with ADI
if (($userinfo["useraccountcontrol"][0] & UF_SMARTCARD_REQUIRED) == 0) {
// get display name
$display_name = $this->_get_display_name_from_AD($username, $userinfo);
// create new users or update them
if (!$user OR (strtolower($user->user_login) != strtolower($username))) { // use strtolower!!!
$user_id = $this->_create_user($ad_username, $userinfo, $display_name, $user_role, '', true);
$added_users++;
} else {
$user_id = $this->_update_user($ad_username, $userinfo, $display_name, $user_role, '', true);
$updated_users++;
}
// load user object (this shouldn't be necessary)
if (!$user_id) {
$user_id = username_exists($username);
$this->_log(ADI_LOG_NOTICE,'user_id: '.$user_id);
}
// if the user is disabled
if (($userinfo["useraccountcontrol"][0] & UF_ACCOUNT_DISABLE) == UF_ACCOUNT_DISABLE)
{
$this->_log(ADI_LOG_INFO,'The user "' . $username .'" is disabled in Active Directory.');
if ($this->_disable_users) {
$this->_log(ADI_LOG_WARN,'Disabling user "' . $username .'".');
$this->_disable_user($user_id, sprintf(__('User "%s" is disabled in Active Directory.', 'ad-integration'), $username));
}
} else {
// Enable user / turn off user_disabled
$this->_log(ADI_LOG_INFO,'Enabling user "' . $username .'".');
$this->_enable_user($user_id);
}
} else {
// Flag UF_SMARTCARD_REQUIRED is set
$this->_log(ADI_LOG_INFO,'The user "' . $username .'" requires a SmartCard to logon.');
if (isset($user->ID) && ($this->_disable_users)) {
$this->_log(ADI_LOG_WARN,'Disabling user "' . $username .'".');
$this->_disable_user($user->ID, sprintf(__('User "%s" requires a SmartCard to logon.', 'ad-integration'), $username));
}
}
} else {
// not a normal user account
$this->_log(ADI_LOG_INFO,'The user "' . $username .'" has no normal user account.');
if (isset($user->ID) && ($this->_disable_users)) {
$this->_log(ADI_LOG_WARN,'Disabling user "' . $username .'".');
$this->_disable_user($user->ID, sprintf(__('User "%s" has no normal user account.', 'ad-integration'), $username));
}
}
}
}
// Logging
$elapsed_time = time() - $time;
$this->_log(ADI_LOG_INFO,$added_users . ' Users added.');
$this->_log(ADI_LOG_INFO,$updated_users . ' Users updated.');
$this->_log(ADI_LOG_INFO,'In '. $elapsed_time . ' seconds.');
$this->_log(ADI_LOG_INFO,"-------------------------------------\n".
"END OF BULK IMPORT\n".
date('Y-m-d / H:i:s')."\n".
"-------------------------------------\n");
return true;
}
It looks like this is where I fails. But why wouldn't it be able to get group?
foreach ($groups AS $group) {
// get all members of group
$group = trim($group);
if ($group != '') {
// do we have a groupid?
if (($pos = stripos($group,'id:')) !== false) {
$pgid = substr($group,$pos+3);
$members = $this->_adldap->group_members_by_primarygroupid($pgid, true);
} else {
$members = $this->_adldap->group_members($group, true);
}
if ($members) {
$this->_log(ADI_LOG_INFO,count($members).' Members of group "'.$group.'".');
$this->_log(ADI_LOG_DEBUG,'Members of group "'.$group.'": ' . implode(', ',$members));
foreach ($members AS $user) {
$all_users[strtolower($user)] = $user;
}
} else {
$this->_log(ADI_LOG_ERROR,'Error retrieving group members for group "'.$group.'".');
}
I removed
$ad_password = $this->_decrypt($this->_bulkimport_pwd);
and added
$ad_password = 'my_password_here';
And it worked
Seems that this decrypt password is broken.
[INFO] 1000 Members of group "id:513".
[INFO] Number of users to import/update: 3439
I had the same problem when I filled twice the field "Bulk Import User Password". I launched the bulk import, which failed (all the users were disabled!). My Apache log below:
PHP Warning: mcrypt_decrypt(): Key of size 27 not supported by this
algorithm.Only keys of sizes 16, 24 or 32 supported in
/var/www/html/wordpress/wp-content/plugins/active-directory-integration/ad-integration.php
The problem seems come from the function mcrypt used to encrypt the password. We can see in the file ad-integration.php that the function used the Wordpress constant AUTH_SALT, which is defined by default like "put your unique phrase here", thus 27 char. So I defined this constant with a string of 32 char (you can define this in wp-config.php). I refilled the Bulk Import User Password and it works.
Related
I would like to set "joomla_remember_me..." cookie from my custom script depending on condition. I would probably need to execute public function onUserAfterLogin from the file \plugins\authentication\cookie\cookie.php with the argument "remember me" set, but I cannot figure out how.
Here's the cookie.php file for the reference:
/**
* Joomla Authentication plugin
*
* #since 3.2
* #note Code based on http://jaspan.com/improved_persistent_login_cookie_best_practice
* and http://fishbowl.pastiche.org/2004/01/19/persistent_login_cookie_best_practice/
*/
class PlgAuthenticationCookie extends JPlugin
{
/**
* Application object
*
* #var JApplicationCms
* #since 3.2
*/
protected $app;
/**
* Database object
*
* #var JDatabaseDriver
* #since 3.2
*/
protected $db;
/**
* Reports the privacy related capabilities for this plugin to site administrators.
*
* #return array
*
* #since 3.9.0
*/
public function onPrivacyCollectAdminCapabilities()
{
$this->loadLanguage();
return array(
JText::_('PLG_AUTHENTICATION_COOKIE') => array(
JText::_('PLG_AUTH_COOKIE_PRIVACY_CAPABILITY_COOKIE'),
)
);
}
/**
* This method should handle any authentication and report back to the subject
*
* #param array $credentials Array holding the user credentials
* #param array $options Array of extra options
* #param object &$response Authentication response object
*
* #return boolean
*
* #since 3.2
*/
public function onUserAuthenticate($credentials, $options, &$response)
{
// No remember me for admin
if ($this->app->isClient('administrator'))
{
return false;
}
// Get cookie
$cookieName = 'joomla_remember_me_' . JUserHelper::getShortHashedUserAgent();
$cookieValue = $this->app->input->cookie->get($cookieName);
// Try with old cookieName (pre 3.6.0) if not found
if (!$cookieValue)
{
$cookieName = JUserHelper::getShortHashedUserAgent();
$cookieValue = $this->app->input->cookie->get($cookieName);
}
if (!$cookieValue)
{
return false;
}
$cookieArray = explode('.', $cookieValue);
// Check for valid cookie value
if (count($cookieArray) !== 2)
{
// Destroy the cookie in the browser.
$this->app->input->cookie->set($cookieName, '', 1, $this->app->get('cookie_path', '/'), $this->app->get('cookie_domain', ''));
JLog::add('Invalid cookie detected.', JLog::WARNING, 'error');
return false;
}
$response->type = 'Cookie';
// Filter series since we're going to use it in the query
$filter = new JFilterInput;
$series = $filter->clean($cookieArray[1], 'ALNUM');
// Remove expired tokens
$query = $this->db->getQuery(true)
->delete('#__user_keys')
->where($this->db->quoteName('time') . ' < ' . $this->db->quote(time()));
try
{
$this->db->setQuery($query)->execute();
}
catch (RuntimeException $e)
{
// We aren't concerned with errors from this query, carry on
}
// Find the matching record if it exists.
$query = $this->db->getQuery(true)
->select($this->db->quoteName(array('user_id', 'token', 'series', 'time')))
->from($this->db->quoteName('#__user_keys'))
->where($this->db->quoteName('series') . ' = ' . $this->db->quote($series))
->where($this->db->quoteName('uastring') . ' = ' . $this->db->quote($cookieName))
->order($this->db->quoteName('time') . ' DESC');
try
{
$results = $this->db->setQuery($query)->loadObjectList();
}
catch (RuntimeException $e)
{
$response->status = JAuthentication::STATUS_FAILURE;
return false;
}
if (count($results) !== 1)
{
// Destroy the cookie in the browser.
$this->app->input->cookie->set($cookieName, '', 1, $this->app->get('cookie_path', '/'), $this->app->get('cookie_domain', ''));
$response->status = JAuthentication::STATUS_FAILURE;
return false;
}
// We have a user with one cookie with a valid series and a corresponding record in the database.
if (!JUserHelper::verifyPassword($cookieArray[0], $results[0]->token))
{
/*
* This is a real attack!
* Either the series was guessed correctly or a cookie was stolen and used twice (once by attacker and once by victim).
* Delete all tokens for this user!
*/
$query = $this->db->getQuery(true)
->delete('#__user_keys')
->where($this->db->quoteName('user_id') . ' = ' . $this->db->quote($results[0]->user_id));
try
{
$this->db->setQuery($query)->execute();
}
catch (RuntimeException $e)
{
// Log an alert for the site admin
JLog::add(
sprintf('Failed to delete cookie token for user %s with the following error: %s', $results[0]->user_id, $e->getMessage()),
JLog::WARNING,
'security'
);
}
// Destroy the cookie in the browser.
$this->app->input->cookie->set($cookieName, '', 1, $this->app->get('cookie_path', '/'), $this->app->get('cookie_domain', ''));
// Issue warning by email to user and/or admin?
JLog::add(JText::sprintf('PLG_AUTH_COOKIE_ERROR_LOG_LOGIN_FAILED', $results[0]->user_id), JLog::WARNING, 'security');
$response->status = JAuthentication::STATUS_FAILURE;
return false;
}
// Make sure there really is a user with this name and get the data for the session.
$query = $this->db->getQuery(true)
->select($this->db->quoteName(array('id', 'username', 'password')))
->from($this->db->quoteName('#__users'))
->where($this->db->quoteName('username') . ' = ' . $this->db->quote($results[0]->user_id))
->where($this->db->quoteName('requireReset') . ' = 0');
try
{
$result = $this->db->setQuery($query)->loadObject();
}
catch (RuntimeException $e)
{
$response->status = JAuthentication::STATUS_FAILURE;
return false;
}
if ($result)
{
// Bring this in line with the rest of the system
$user = JUser::getInstance($result->id);
// Set response data.
$response->username = $result->username;
$response->email = $user->email;
$response->fullname = $user->name;
$response->password = $result->password;
$response->language = $user->getParam('language');
// Set response status.
$response->status = JAuthentication::STATUS_SUCCESS;
$response->error_message = '';
}
else
{
$response->status = JAuthentication::STATUS_FAILURE;
$response->error_message = JText::_('JGLOBAL_AUTH_NO_USER');
}
}
/**
* We set the authentication cookie only after login is successfullly finished.
* We set a new cookie either for a user with no cookies or one
* where the user used a cookie to authenticate.
*
* #param array $options Array holding options
*
* #return boolean True on success
*
* #since 3.2
*/
public function onUserAfterLogin($options)
{
// No remember me for admin
if ($this->app->isClient('administrator'))
{
return false;
}
if (isset($options['responseType']) && $options['responseType'] === 'Cookie')
{
// Logged in using a cookie
$cookieName = 'joomla_remember_me_' . JUserHelper::getShortHashedUserAgent();
// We need the old data to get the existing series
$cookieValue = $this->app->input->cookie->get($cookieName);
// Try with old cookieName (pre 3.6.0) if not found
if (!$cookieValue)
{
$oldCookieName = JUserHelper::getShortHashedUserAgent();
$cookieValue = $this->app->input->cookie->get($oldCookieName);
// Destroy the old cookie in the browser
$this->app->input->cookie->set($oldCookieName, '', 1, $this->app->get('cookie_path', '/'), $this->app->get('cookie_domain', ''));
}
$cookieArray = explode('.', $cookieValue);
// Filter series since we're going to use it in the query
$filter = new JFilterInput;
$series = $filter->clean($cookieArray[1], 'ALNUM');
}
elseif (!empty($options['remember']))
{
// Remember checkbox is set
$cookieName = 'joomla_remember_me_' . JUserHelper::getShortHashedUserAgent();
// Create a unique series which will be used over the lifespan of the cookie
$unique = false;
$errorCount = 0;
do
{
$series = JUserHelper::genRandomPassword(20);
$query = $this->db->getQuery(true)
->select($this->db->quoteName('series'))
->from($this->db->quoteName('#__user_keys'))
->where($this->db->quoteName('series') . ' = ' . $this->db->quote($series));
try
{
$results = $this->db->setQuery($query)->loadResult();
if ($results === null)
{
$unique = true;
}
}
catch (RuntimeException $e)
{
$errorCount++;
// We'll let this query fail up to 5 times before giving up, there's probably a bigger issue at this point
if ($errorCount === 5)
{
return false;
}
}
}
while ($unique === false);
}
else
{
return false;
}
// Get the parameter values
$lifetime = $this->params->get('cookie_lifetime', 60) * 24 * 60 * 60;
$length = $this->params->get('key_length', 16);
// Generate new cookie
$token = JUserHelper::genRandomPassword($length);
$cookieValue = $token . '.' . $series;
// Overwrite existing cookie with new value
$this->app->input->cookie->set(
$cookieName,
$cookieValue,
time() + $lifetime,
$this->app->get('cookie_path', '/'),
$this->app->get('cookie_domain', ''),
$this->app->isHttpsForced(),
true
);
$query = $this->db->getQuery(true);
if (!empty($options['remember']))
{
// Create new record
$query
->insert($this->db->quoteName('#__user_keys'))
->set($this->db->quoteName('user_id') . ' = ' . $this->db->quote($options['user']->username))
->set($this->db->quoteName('series') . ' = ' . $this->db->quote($series))
->set($this->db->quoteName('uastring') . ' = ' . $this->db->quote($cookieName))
->set($this->db->quoteName('time') . ' = ' . (time() + $lifetime));
}
else
{
// Update existing record with new token
$query
->update($this->db->quoteName('#__user_keys'))
->where($this->db->quoteName('user_id') . ' = ' . $this->db->quote($options['user']->username))
->where($this->db->quoteName('series') . ' = ' . $this->db->quote($series))
->where($this->db->quoteName('uastring') . ' = ' . $this->db->quote($cookieName));
}
$hashedToken = JUserHelper::hashPassword($token);
$query->set($this->db->quoteName('token') . ' = ' . $this->db->quote($hashedToken));
try
{
$this->db->setQuery($query)->execute();
}
catch (RuntimeException $e)
{
return false;
}
return true;
}
/**
* This is where we delete any authentication cookie when a user logs out
*
* #param array $options Array holding options (length, timeToExpiration)
*
* #return boolean True on success
*
* #since 3.2
*/
public function onUserAfterLogout($options)
{
// No remember me for admin
if ($this->app->isClient('administrator'))
{
return false;
}
$cookieName = 'joomla_remember_me_' . JUserHelper::getShortHashedUserAgent();
$cookieValue = $this->app->input->cookie->get($cookieName);
// There are no cookies to delete.
if (!$cookieValue)
{
return true;
}
$cookieArray = explode('.', $cookieValue);
// Filter series since we're going to use it in the query
$filter = new JFilterInput;
$series = $filter->clean($cookieArray[1], 'ALNUM');
// Remove the record from the database
$query = $this->db->getQuery(true)
->delete('#__user_keys')
->where($this->db->quoteName('series') . ' = ' . $this->db->quote($series));
try
{
$this->db->setQuery($query)->execute();
}
catch (RuntimeException $e)
{
// We aren't concerned with errors from this query, carry on
}
// Destroy the cookie
$this->app->input->cookie->set($cookieName, '', 1, $this->app->get('cookie_path', '/'), $this->app->get('cookie_domain', ''));
return true;
}
}
Thanks in advance :)
It's a very complex process and I think you would be better off cloning this plugin to a new name, adding your condition to the function, unpublish the current plugin and publish your new one instead. You will also have to watch for any changes to the original plugin in case a security issue is found.
I have Yii2 project. And there I also have api written by Symfony.
In Symfony part I have method in the class which send request to Yii controller.
$buzz = $this->container->get('buzz');
$buzz->getClient()->setVerifyHost(false);
$buzz->getClient()->setVerifyPeer(false);
$buzz->getClient()->setTimeOut(false);
$url = $this->container->getParameter('integra_sync_prices');
$sendResult = $buzz->post($url, array('authorization' => $this->container->getParameter('load_token')), array('products' =>
json_encode($productPrices)));
$resultJson = json_decode($sendResult->getContent(), true);
if (isset($resultJson['error']))
throw new \Exception('Site: '.$resultJson['error'], 500);
class IntegraController extends Controller{
public function actionIndex()
{
Yii::$app->response->format = Response::FORMAT_JSON;
$headers = Yii::$app->request->getHeaders();
foreach ($headers as $key => $value) {
if(strtolower(trim($key)) == 'authorization') {
$token = trim($value[0]);
break;
}
}
$products = json_decode(Yii::$app->request->post('products'));
$post_products = Yii::$app->request->post('products');
if('111' == $token) {
if(isset($post_products) && $products) {
foreach ($products as $product) {
echo $product->price." = ".$product->productId."<br>";
Yii::$app->db->createCommand("UPDATE oc_product SET quantity = '" . (int)$product->quantity . "', price = '" . (float)$product->price . "' WHERE product_id = '" . (int)$product->productId . "'")->execute();
}
$json['success'] = 'complete';
} else {
$json['error'] = 'empty data';
}
} else {
$json['error'] = 'authorization error';
}
Yii::$app->controller->enableCsrfValidation = false;
echo json_encode($json);
}
I expect that data in my database will be updated by this controller. But there in nothing changes.
What do I do wrong? Maybe I should send some another headers? Thanks a lot )
I'm trying to figure out how to give a good response status to my API shot which was made to the prestashop.
That's the code of validation.php:
<?php
class InpayValidationModuleFrontController extends ModuleFrontController
{
/**
* #see FrontController::postProcess()
*/
public function postProcess()
{
if ($_SERVER['REQUEST_METHOD'] == 'POST' && $_POST['invoiceCode'] && $_POST['status'] && $_POST['optData']) {
$apiHash = $_SERVER['HTTP_API_HASH'];
$query = http_build_query($_POST);
$hash = hash_hmac("sha512", $query, $this->module->secret_key);
if ($apiHash == $hash) {
PrestaShopLogger::addLog(json_encode(_PS_VERSION_), 1);
parse_str($_POST['optData'], $optData);
$id_cart = intval($optData['cartId']);
$query = "SELECT * from " . _DB_PREFIX_ . "orders where id_cart='" . $id_cart . "'";
//$query = "SELECT * from aps_orders where id_cart='67867'";
$row = Db::getInstance()->getRow($query);
if ($_POST['status'] == 'confirmed' && $row['current_state'] != null) {
$sql = "UPDATE " . _DB_PREFIX_ . "orders SET current_state='2' WHERE id_cart='" . $id_cart . "'";
if(Db::getInstance()->Execute($sql))
Tools::redirect(__FILE__,'payment_confirmation.tpl');
} else {
$cart = new Cart($id_cart);
if ($cart->id_customer == 0 || $cart->id_address_delivery == 0 || $cart->id_address_invoice == 0 || !$this->module->active) {
//die('Cannot create order for this cart.');
Tools::redirect(__FILE__,'payment_cart_error.tpl');
}
$customer = new Customer($cart->id_customer);
if (!Validate::isLoadedObject($customer)) {
//die('No customer for this order.');
Tools::redirect(__FILE__,'payment_customer_error.tpl');
}
$currency = new Currency((int)($cart->id_currency));
$paid_amount = $_POST['amount'];
$order_amount = $cart->getOrderTotal(true, Cart::BOTH);
if ($_POST['status'] == 'confirmed') {
$paymentId = 2;
} elseif ($_POST['status'] == 'received') {
$paymentId = 11;
}
$result = $this->module->validateOrder(
$cart->id,
//Configuration::get('PS_OS_PAYMENT'),
$paymentId,
$order_amount,
$this->module->displayName,
'Invoice Code: ' . $_POST['invoiceCode'],
array(),
intval($currency->id),
false,
$customer->secure_key
);
//die($result);
Tools::redirect(__FILE__,'payment_confirmation.tpl');
}
} else {
return null;
}
}
}
}
While I use the die(); function the server returns 200 response status which is good... but the die isn't a function for production... When using redirect it gives me 302 and additional status of error. I tried doing hacks like:
header("HTTP/1.1 200 OK");
or
return http_response_code(200);
But the status is 500. I would appreciate any tip or help how to do that.
Cheers!
You are trying to redirect directly to the tpl file. You should redirect to a controller or url. For exampl, in the module cheque, in the payment.php there is:
Tools::redirect(Context::getContext()->link->getModuleLink('cheque', 'payment'));
or in validation.php:
Tools::redirect('index.php?controller=order-confirmation&id_cart='.(int)$cart->id.'&id_module='.(int)$this->module->id.'&id_order='.$this->module->currentOrder.'&key='.$customer->secure_key);
Also, Tools::redirect is defined as:
redirect($url, $base_uri = __PS_BASE_URI__, Link $link = null, $headers = null)
On the other hand, you can be trying to use the display function used in modules (for example):
return $this->display(__FILE__, 'file.tpl');
But in this case you should use the assign and setTemplate:
$this->context->smarty->assign(array(/* array of vars to use in tpl*/));
$this->setTemplate('file.tpl');
I have an issue where I need to data from a RETS server and populate it on the database, I was able to get all but two tables to properly automate this data in, but I'm having issues with the last (and biggest) two. After looking at it, the issue is timeout with the server, it cannot finish in time for the database to populate.
I am working off of a godaddy server and already have the maximum time I can set for the program to run, the only thing I can do now is figure out a way to speed up my code so it finishes in time, and would like some help figuring that out.
The code (posted below) was modified to fit my needs from here: https://github.com/coreyrowell/retshelper/blob/master/rets_helper.php
While it works well and I was able to get it working, I haven't been able to figure out the best way to speed it up. Any help would be sincerely appreciated.
<?php
/*
.---------------------------------------------------------------------------.
| Software: RETSHELPER - PHP Class to interface RETS with Database |
| Version: 1.0 |
| Contact: corey#coreyrowell.com |
| Info: None |
| Support: corey#coreyrowell.com |
| ------------------------------------------------------------------------- |
| Author: Corey Rowell - corey#coreyrowell.com |
| Copyright (c) 2013, Corey Rowell. All Rights Reserved. |
| ------------------------------------------------------------------------- |
| License: This content is released under the |
| (http://opensource.org/licenses/MIT) MIT License. | |
'---------------------------------------------------------------------------'
*/
/*
.---------------------------------------------------------------------------.
| This software requires the use of the PHPRETS library |
| http://troda.com/projects/phrets/ |
'---------------------------------------------------------------------------'
*/
define("BASE_PATH",dirname(__FILE__)."/");
ini_set('mysql.connect_timeout',0);
ini_set('default_socket_timeout',0);
class RETSHELPER
{
// Defaults
private $rets, $auth, $config, $database, $mysqli, $data, $log, $scriptstart, $scriptend,
$previous_start_time, $current_start_time, $updates_log, $active_ListingRids = array();
public function __construct()
{
// Require PHRETS library
require_once("phrets.php");
// Start rets connection
$this->rets = new phRETS;
$this->scriptstart = date("m-d-y_h-i-s", time());
// RETS Server Info
$this->auth['url'] = 'redacted';//MLS_URL;//MLS_URL;
$this->auth['username'] = 'redacted'; //MLS_USERNAME;
$this->auth['password'] = 'redacted'; //MLS_PASS;
$this->auth['retsversion'] = ''; //USER Agent Version
$this->auth['useragent'] = ''; //USER Agent
// RETS Options
$this->config['property_classes'] = array("A");//,"B","C","D","E","F");
$this->config['KeyField'] = "LIST_1";
$this->config['offset_support'] = TRUE; // Enable if RETS server supports 'offset'
$this->config['useragent_support'] = FALSE;
$this->config['images_path'] = BASE_PATH."listing_photos/";
$this->config['logs_path'] = BASE_PATH."logs/";
$this->config['start_times_path'] = BASE_PATH."logs/";
$this->config['previous_start_time'] = $this->get_previous_start_time();
$this->config['create_tables'] = FALSE; // Create tables for classes (terminates program)
// Log to screen?
$this->config['to_screen'] = TRUE;
// Database Config
$this->database['host'] = 'redacted'; //DB_SERVER;
$this->database['username'] = 'redacted'; //DB_USER;
$this->database['password'] = 'redacted'; //DB_PASS;
$this->database['database'] = 'redacted'; //DB_NAME;
$this->config_init();
// Load the run function
$this->run();
}
private function config_init()
{
// Set offset support based on config
if($this->config['offset_support'])
{
$this->rets->SetParam("offset_support", true);
} else {
$this->rets->SetParam("offset_support", false);
}
if($this->config['useragent_support'])
{
$this->rets->AddHeader("RETS-Version", $this->auth['retsversion']);
$this->rets->AddHeader("User-Agent", $this->auth['useragent']);
}
}
public function run()
{
// Start Logging
$this->logging_start();
// RETS Connection
$this->connect();
// Connect to Database
$this->database_connect();
if($this->config['create_tables'])
{
$this->log_data("Creating database tables, program will exit after finishing.");
foreach ($this->config['property_classes'] as $class)
{
$this->log_data("Creating table for: " . $class);
$this->create_table_for_property_class($class);
}
$this->log_data("Exiting program.");
return;
}
// Get Properties (and images)
$this->get_properties_by_class();
// Close RETS Connection
$this->disconnect();
// Delete inactive listings
$this->database_delete_records();
// Insert new listings
$this->database_insert_records();
// Disconnect from Database
$this->database_disconnect();
// End Logging
$this->logging_end();
// Time for next scheduled update
$this->set_previous_start_time();
}
private function connect()
{
$this->log_data("Connecting to RETS...");
// Connect to RETS
$connect = $this->rets->Connect($this->auth['url'], $this->auth['username'], $this->auth['password']);
if($connect)
{
$this->log_data("Successfully connected to RETS.");
return TRUE;
} else {
$error = $this->rets->Error();
if($error['text'])
{
$error = $error['text'];
} else {
$error = "No error message returned from RETS. Check RETS debug file.";
}
$this->log_error("Failed to connect to RETS.\n".$error);
die();
}
}
private function get_properties_by_class()
{
$this->log_data("Getting Classes...");
foreach ($this->config['property_classes'] as $class)
{
$this->log_data("Getting Class: ".$class);
// Set
$fields_order = array();
$mod_timestamp_field = $this->get_timestamp_field($class);
$previous_start_time = $this->config['previous_start_time'];
$search_config = array('Format' => 'COMPACT-DECODED', 'QueryType' => 'DMQL2', 'Limit'=> 1000, 'Offset' => 1, 'Count' => 1);
/*--------------------------------------------------------------------------------.
| |
| If you're having problems, they probably lie here in the $query and/or $search. |
| |
'--------------------------------------------------------------------------------*/
// Query
$query = "({$mod_timestamp_field}=2016-09-16T00:00:00-2016-09-16T01:00:00)";//{$previous_start_time}+)";
// Run Search
$search = $this->rets->SearchQuery("Property", $class, $query, $search_config);
// Get all active listings
$query_all = "({$mod_timestamp_field}=1980-01-01T00:00:00+)";
$search_all = $this->rets->SearchQuery("Property", $class, $query_all, array('Format'=>'COMPACT', 'Select'=>$this->config['KeyField']));
$tmpArray = array();
while($active_rid = $this->rets->FetchRow($search_all)) {
array_push($tmpArray, $active_rid[$this->config['KeyField']]);
}
$this->active_ListingRids['property_'.strtolower($class)] = $tmpArray;
$data = array();
if ($this->rets->NumRows($search) > 0)
{
// Get columns
$fields_order = $this->rets->SearchGetFields($search);
$this->data['headers'] = $fields_order;
// Process results
while ($record = $this->rets->FetchRow($search))
{
$this_record = array();
// Loop it
foreach ($fields_order as $fo)
{
$this_record[$fo] = $record[$fo];
}
$ListingRid = $record[$this->config['KeyField']];
$data[] = $this_record;
}
}
// Set data
$this->data['classes'][$class] = $data;
$this->log_data("Finished Getting Class: ".$class . "\nTotal found: " .$this->rets->TotalRecordsFound());
// Free RETS Result
$this->rets->FreeResult($search);
}
}
private function get_timestamp_field($class)
{
$class = strtolower($class);
switch($class)
{
case 'a':
$field = "LIST_87";
break;
}
return $field;
}
private function disconnect()
{
$this->log_data("Disconnected from RETS.");
$this->rets->Disconnect();
}
private function database_connect()
{
$this->log_data("Connecting to database...");
$host = $this->database['host'];
$username = $this->database['username'];
$password = $this->database['password'];
$database = $this->database['database'];
// Create connection
$this->mysqli = new mysqli($host, $username, $password, $database);
// Throw error if connection fails
if ($this->mysqli->connect_error) {
$this->log_error("Database Connection Error". $this->mysqli->connect_error);
die('Connect Error (' . $this->mysqli->connect_errno . ') '
. $this->mysqli->connect_error);
}
}
private function database_delete_records()
{
$this->log_data("Updating database...");
// Loop through each table and update
foreach($this->config['property_classes'] as $class)
{
// Get Tables
$table = "rets_property_".strtolower($class);
$activeListings = $this->active_ListingRids['property_'.strtolower($class)];
$sql = "DELETE FROM {$table} WHERE {$this->config['KeyField']} NOT IN (".implode(',', $activeListings).");";
$this->mysqli->query($sql);
if($this->mysqli->affected_rows > 0)
{
$this->log_data("Deleted {$this->mysqli->affected_rows} Listings.");
// return TRUE;
} else if($this->mysqli->affected_rows == 0) {
$this->log_data("Deleted {$this->mysqli->affected_rows} Listings.");
} else {
$this->log_data("Deleting database records failed \n\n" . mysqli_error($this->mysqli));
// return FALSE;
}
}
}
private function database_insert_records()
{
$this->log_data("Inserting records...");
foreach($this->config['property_classes'] as $class)
{
// Get Tables
$table = "rets_property_".strtolower($class);
// Get data
$data_row = $this->data['classes'][$class];
// Defaults
$total_rows = 0;
$total_affected_rows = 0;
// Loop through data
foreach($data_row as $drow)
{
// Clean data
// replace empty with NULL
// and wrap data in quotes
$columns = array();
$values = array();
foreach($drow as $key => $val)
{
if($val === '')
{
$val = '""';
} else {
$val = mysqli_real_escape_string($this->mysqli ,$val);
$val = "'$val'";
}
$columns[] = $key;
$values[] = $val;
}
// Implode data rows with commas
$values = implode(', ', $values);
$columns = implode(', ', $columns);
// Build SQL
$sql = "REPLACE INTO {$table} ({$columns}) VALUES ({$values})";
// Do query
$this->mysqli->query($sql);
if($this->mysqli->affected_rows > 0)
{
$total_affected_rows++;
} else {
$this->log_error("Failed to insert the following record: ".$sql . "\n\n" . mysqli_error($this->mysqli));
}
$total_rows++;
}
$this->log_data("Done inserting data. ".$class."\nTotal Records: ".$total_rows." .\nTotal Inserted: ".$total_affected_rows);
}
}
private function database_disconnect()
{
$this->log_data("Database disconnected...");
// Close connection
$this->mysqli->close();
}
private function create_table_for_property_class($class)
{
// gets resource information. need this for the KeyField
$rets_resource_info = $this->rets->GetMetadataInfo();
$resource = "Property";
// pull field format information for this class
$rets_metadata = $this->rets->GetMetadata($resource, $class);
$table_name = "rets_".strtolower($resource)."_".strtolower($class);
// i.e. rets_property_resi
$sql = $this->create_table_sql_from_metadata($table_name, $rets_metadata, $rets_resource_info[$resource]['KeyField']);
$this->mysqli->query($sql);
}
private function create_table_sql_from_metadata($table_name, $rets_metadata, $key_field, $field_prefix = "")
{
$sql_query = "CREATE TABLE {$table_name} (\n";
foreach ($rets_metadata as $field) {
$field['SystemName'] = "`{$field_prefix}{$field['SystemName']}`";
$cleaned_comment = addslashes($field['LongName']);
$sql_make = "{$field['SystemName']} ";
if ($field['Interpretation'] == "LookupMulti") {
$sql_make .= "TEXT";
}
elseif ($field['Interpretation'] == "Lookup") {
$sql_make .= "VARCHAR(50)";
}
elseif ($field['DataType'] == "Int" || $field['DataType'] == "Small" || $field['DataType'] == "Tiny") {
$sql_make .= "INT({$field['MaximumLength']})";
}
elseif ($field['DataType'] == "Long") {
$sql_make .= "BIGINT({$field['MaximumLength']})";
}
elseif ($field['DataType'] == "DateTime") {
$sql_make .= "DATETIME default '0000-00-00 00:00:00' not null";
}
elseif ($field['DataType'] == "Character" && $field['MaximumLength'] <= 255) {
$sql_make .= "VARCHAR({$field['MaximumLength']})";
}
elseif ($field['DataType'] == "Character" && $field['MaximumLength'] > 255) {
$sql_make .= "TEXT";
}
elseif ($field['DataType'] == "Decimal") {
$pre_point = ($field['MaximumLength'] - $field['Precision']);
$post_point = !empty($field['Precision']) ? $field['Precision'] : 0;
$sql_make .= "DECIMAL({$field['MaximumLength']},{$post_point})";
}
elseif ($field['DataType'] == "Boolean") {
$sql_make .= "CHAR(1)";
}
elseif ($field['DataType'] == "Date") {
$sql_make .= "DATE default '0000-00-00' not null";
}
elseif ($field['DataType'] == "Time") {
$sql_make .= "TIME default '00:00:00' not null";
}
else {
$sql_make .= "VARCHAR(255)";
}
$sql_make .= " COMMENT '{$cleaned_comment}'";
$sql_make .= ",\n";
$sql_query .= $sql_make;
}
$sql_query .= "`Photos` TEXT COMMENT 'Photos Array', ";
$sql_query .= "PRIMARY KEY(`{$field_prefix}{$key_field}`) )";
return $sql_query;
}
private function get_previous_start_time()
{
$filename = "previous_start_time_A.txt";
// See if file exists
if(file_exists($this->config['start_times_path'].$filename))
{
$time=time();
$this->updates_log = fopen($this->config['start_times_path'].$filename, "r+");
$this->previous_start_time = fgets($this->updates_log);
$this->current_start_time = date("Y-m-d", $time) . 'T' . date("H:i:s", $time);
} else {
// Create file
$this->updates_log = fopen($this->config['start_times_path'].$filename, "w+");
fwrite($this->updates_log, "1980-01-01T00:00:00\n");
$this->get_previous_start_time();
}
// fgets reads up to & includes the first newline, strip it
return str_replace("\n", '', $this->previous_start_time);
}
private function set_previous_start_time()
{
$file = $this->config['start_times_path'] . "previous_start_time_A.txt";
$file_data = $this->current_start_time."\n";
$file_data .= file_get_contents($file);
file_put_contents($file, $file_data);
}
private function logging_start()
{
$filename = "Log".date("m-d-y_h-i-s", time()).".txt";
// See if file exists
if(file_exists($this->config['logs_path'].$filename))
{
$this->log = fopen($this->config['logs_path'].$filename, "a");
} else {
// Create file
$this->log = fopen($this->config['logs_path'].$filename, "w+");
}
}
private function log_data($data)
{
$write_data = "\nInfo Message: [".date("m/d/y - h:i:s", time())."]\n------------------------------------------------\n";
$write_data .= $data."\n";
$write_data .= "\n------------------------------------------------\n";
fwrite($this->log, $write_data);
if($this->config['to_screen'])
{
echo str_replace(array("\n"), array('<br />'), $write_data);
}
}
private function log_error($error)
{
$write_data = "\nError Message: [".date("m/d/y - h:i:s", time())."]\n------------------------------------------------\n";
$write_data .= $error."\n";
$write_data .= "\n------------------------------------------------\n";
fwrite($this->log, $write_data);
if($this->config['to_screen'])
{
echo str_replace(array("\n"), array('<br />'), $write_data);
}
}
private function logging_end()
{
$this->scriptend = date("m-d-y_h-i-s", time());
$this->log_data("Closing log file.\n
Start Time: {$this->scriptstart}\n
End Time: {$this->scriptend}");
fclose($this->log);
}
}
// Load the class
$retshelper = new RETSHELPER;
Sorry for the wall of code; I would shorten it down but I'm at a loss with what is still needed and what isn't. Once again, any help would or a point into the right direction would be appreciated.
Thank you StackOverflow experts for looking at my question.
First, It is possible this question has been asked before but my situation is a bit unique. So, please hear me out.
When our users want to edit an existing record, they would also like to have the ability to delete an existing pdf file if one exists before adding a new one.
To display an existing file, I use this code.
<td class="td_input_form">
<?php
// if the BidIDFile is empty,
if(empty($result["BidIDFile"]))
{
//then show file upload field for Bid File
echo '<input type="file" name="BidIDFile[]" size="50">';
}
else
{
// Bid file already upload, show checkbox to delete it.
echo '<input type="checkbox" name="delete[]" value="'.$result["BidIDFile"].'"> (delete)
'.$result["BidIDFile"].'';
}
</td>
Then to delete this file, I use the following code:
// Connect to SQL Server database
include("connections/Connect.php");
// Connect to SQL Server database
include("connections/Connect.php");
$strsID = isset($_GET["Id"]) ? $_GET["Id"] : null;
if(isset($_POST['delete']))
{
// whilelisted table columns
$fileColumnsInTable = array( 'BidIDFile', 'TabSheet', 'SignInSheet', 'XConnect',
'Addend1', 'Addend2','Addend3','Addend4','Addend5', 'Addend6');
$fileColumns = array();
foreach ($_POST['delete'] as $fileColumn)
{
if(in_array($fileColumn, $fileColumnsInTable))
$fileColumns[] = $fileColumn;
}
// get the file paths for each file to be deleted
$stmts = "SELECT " . implode(', ', $fileColumns) . " FROM bids WHERE ID = ? ";
$querys = sqlsrv_query( $conn, $stmts, array($strsID));
$files = sqlsrv_fetch_array($querys,SQLSRV_FETCH_ROW);
// loop over the files returned by the query
foreach ($files as $file )
{
//delete file
unlink($file);
}
// now remove the values from the table
$stmts = "UPDATE bids SET " . impload(' = '', ', $fields) . " WHERE ID = ? ";
$querys = sqlsrv_query( $conn, $stmts, array($strsID));
This works fine. However, the edit file points to an existing file with an INSERT and UPDATE operation in this one file (great thanks to rasclatt) and I am having problem integrating the two together.
Can someone please help with integrating the two files into one?
Thanks in advance for your assistance.
Here is the INSERT and UPDATE file:
<?php
error_reporting(E_ALL);
class ProcessBid
{
public $data;
public $statement;
public $where_vals;
protected $keyname;
protected $conn;
public function __construct($conn = false)
{
$this->conn = $conn;
}
public function SaveData($request = array(),$skip = false,$keyname = 'post')
{
$this->keyname = $keyname;
$this->data[$this->keyname] = $this->FilterRequest($request,$skip);
return $this;
}
public function FilterRequest($request = array(), $skip = false)
{
// See how many post variables are being sent
if(count($request) > 0) {
// Loop through post
foreach($request as $key => $value) {
// Use the skip
if($skip == false || (is_array($skip) && !in_array($key,$skip))) {
// Create insert values
$vals['vals'][] = "'".ms_escape_string($value)."'";
// Create insert columns
$vals['cols'][] = "".str_replace("txt","",$key)."";
// For good measure, create an update string
$vals['update'][] = "".str_replace("txt","",$key)."".' = '."'".ms_escape_string($value)."'";
// For modern day binding, you can use this array
$vals['bind']['cols'][] = "".$key."";
$vals['bind']['cols_bind'][] = ":".$key;
$vals['bind']['vals'][":".$key] = $value;
$vals['bind']['update'][] = "".$key.' = :'.$key;
}
}
}
return (isset($vals))? $vals:false;
}
public function AddFiles($name = 'item')
{
// If the files array has been set
if(isset($_FILES[$name]['name']) && !empty($_FILES[$name]['name'])) {
// Remove empties
$_FILES[$name]['name'] = array_filter($_FILES[$name]['name']);
$_FILES[$name]['type'] = array_filter($_FILES[$name]['type']);
$_FILES[$name]['size'] = array_filter($_FILES[$name]['size']);
$_FILES[$name]['tmp_name'] = array_filter($_FILES[$name]['tmp_name']);
// we need to differentiate our type array names
$use_name = ($name == 'item')? 'Addend':$name;
// To start at Addendum1, create an $a value of 1
$a = 1;
if(!empty($_FILES[$name]['tmp_name'])) {
foreach($_FILES[$name]['name'] as $i => $value ) {
$file_name = ms_escape_string($_FILES[$name]['name'][$i]);
$file_size = $_FILES[$name]['size'][$i];
$file_tmp = $_FILES[$name]['tmp_name'][$i];
$file_type = $_FILES[$name]['type'][$i];
if(move_uploaded_file($_FILES[$name]['tmp_name'][$i], $this->target.$file_name)) {
// Format the key values for addendum
if($name == 'item')
$arr[$use_name.$a] = $file_name;
// Format the key values for others
else
$arr[$use_name] = $file_name;
$sql = $this->FilterRequest($arr);
// Auto increment the $a value
$a++;
}
}
}
}
if(isset($sql) && (isset($i) && $i == (count($_FILES[$name]['tmp_name'])-1)))
$this->data[$name] = $sql;
return $this;
}
public function SaveFolder($target = '../uploads/')
{
$this->target = $target;
// Makes the folder if not already made.
if(!is_dir($this->target))
mkdir($this->target,0755,true);
return $this;
}
public function where($array = array())
{
$this->where_vals = NULL;
if(is_array($array) && !empty($array)) {
foreach($array as $key => $value) {
$this->where_vals[] = $key." = '".ms_escape_string($value)."'";
}
}
return $this;
}
public function UpdateQuery()
{
$this->data = array_filter($this->data);
if(empty($this->data)) {
$this->statement = false;
return $this;
}
if(isset($this->data) && !empty($this->data)) {
foreach($this->data as $name => $arr) {
$update[] = implode(",",$arr['update']);
}
}
$vars = (isset($update) && is_array($update))? implode(",",$update):"";
// Check that both columns and values are set
$this->statement = (isset($update) && !empty($update))? "update bids set ".implode(",",$update):false;
if(isset($this->where_vals) && !empty($this->where_vals)) {
$this->statement .= " where ".implode(" and ",$this->where_vals);
}
return $this;
}
public function SelectQuery($select = "*",$table = 'bids')
{
$stmt = (is_array($select) && !empty($select))? implode(",",$select):$select;
$this->statement = "select ".$stmt." from ".$table;
return $this;
}
public function InsertQuery($table = 'bids')
{
$this->data = array_filter($this->data);
if(empty($this->data)) {
$this->statement = false;
return $this;
}
$this->statement = "insert into ".$table;
if(isset($this->data) && !empty($this->data)) {
foreach($this->data as $name => $arr) {
$insert['cols'][] = implode(",",$arr['cols']);
$insert['vals'][] = implode(",",$arr['vals']);
}
}
$this->statement .= '(';
$this->statement .= (isset($insert['cols']) && is_array($insert['cols']))? implode(",",$insert['cols']):"";
$this->statement .= ") VALUES (";
$this->statement .= (isset($insert['vals']) && is_array($insert['vals']))? implode(",",$insert['vals']):"";
$this->statement .= ")";
return $this;
}
}
include("../Connections/Connect.php");
function render_error($settings = array("title"=>"Failed","body"=>"Sorry, your submission failed. Please go back and fill out all required information."))
{ ?>
<h2><?php echo (isset($settings['title']))? $settings['title']:"Error"; ?></h2>
<p><?php echo (isset($settings['body']))? $settings['body']:"An unknown error occurred."; ?></p>
<?php
}
// this function is used to sanitize code against sql injection attack.
function ms_escape_string($data)
{
if(!isset($data) || empty($data))
return "";
if(is_numeric($data))
return $data;
$non_displayables[] = '/%0[0-8bcef]/'; // url encoded 00-08, 11, 12, 14, 15
$non_displayables[] = '/%1[0-9a-f]/'; // url encoded 16-31
$non_displayables[] = '/[\x00-\x08]/'; // 00-08
$non_displayables[] = '/\x0b/'; // 11
$non_displayables[] = '/\x0c/'; // 12
$non_displayables[] = '/[\x0e-\x1f]/'; // 14-31
foreach($non_displayables as $regex)
$data = preg_replace($regex,'',$data);
$data = str_replace("'","''",$data);
return $data;
}
// New bid save engine is required for both sql statement generations
$BidSet = new ProcessBid($conn);
$strId = null;
if(isset($_POST["Id"]))
{
$strId = $_POST["Id"];
//echo $strId;
}
If ($strId == "") {
//echo "This is an insert statement";
// This will generate an insert query
$insert = $BidSet->SaveData($_POST)
->SaveFolder('../uploads/')
->AddFiles('BidIDFile')
->AddFiles('item')
->AddFiles('SignInSheet')
->AddFiles('TabSheet')
->AddFiles('Xcontract')
->InsertQuery()
->statement;
// Check that statement is not empty
if($insert != false) {
sqlsrv_query($conn,$insert);
render_error(array("title"=>"Bid Successfully Saved!","body"=>'Go back to Solicitation screen'));
$err = false;
}
//echo '<pre>';
//print_r($insert);
// echo '</pre>';
}
else
{
//echo "This is an update statement";
// This will generate an update query
$update = $BidSet->SaveData($_POST,array("Id"))
->SaveFolder('../uploads/')
->AddFiles('BidIDFile')
->AddFiles('item')
->AddFiles('SignInSheet')
->AddFiles('TabSheet')
->AddFiles('Xcontract')
->where(array("Id"=>$_POST["Id"]))
->UpdateQuery()
->statement;
//echo '<pre>';
//print_r($update);
//echo '</pre>';
// Check that statement is not empty
if($update != false) {
sqlsrv_query($conn,$update);
render_error(array("title"=>"Bid Successfully Saved!","body"=>'Go back to admin screen'));
$err = false;
}
}
// This will post an error if the query fails
if((isset($err) && $err == true) || !isset($err))
render_error(); ?>