I'm running into an issue in my CakePHP (2.4.1) app where the virtual field in one of my models is not properly being decrypted using Cake's Security::rijndael(). In my User model, the display field is defined as
public $virtualFields = array( 'name' => 'CONCAT(User.first_name, " ", User.last_name)' );
Both User.first_name and User.last_name are encrypted, and User.name is the displayField for the model. In the AssignedShift related model (User hasMany AssignedShift), the User.name field is not being properly decrypted. Here is an example return:
Array(
[1] => Test|�d�F�3��������������S0�Dy=>�dJ���sP�4�F�n�s-#���7P���n�ʙ.�C�#���˷C�z��(;Eu)�
)
This is the only model that this happens on, so I'm pretty confident my afterFind method is working properly. In any case, below are the functions for encrypt/decrypt:
/*AppModel.php*/
function _afterFind($results, $primary) {
if( $primary ) {
foreach( $results as $key => $val) {
if( isset( $val[$this->alias] ) ) {
$results[$key][$this->alias] = $this->doAfterFind( $results[$key][$this->alias] );
}
}
} else {
if( isset( $results['id']) ) {
$results = $this->doAfterFind($results);
} else {
foreach( $results as $key => $val ) {
if( isset( $val[$this->alias] ) ) {
if( isset( $val[$this->alias]['id'] ) ) {
$results[$key][$this->alias] = $this->doAfterFind( $results[$key][$this->alias] );
} else {
foreach( $results[$key][$this->alias] as $key2 => $val2 ) {
$results[$key][$this->alias][$key2] = $this->doAfterFind( $results[$key][$this->alias][$key2] );
}
}
}
}
}
}
return $results;
}
public function doAfterFind($data) {
foreach( $data as $key => $val) {
if( !empty( $val ) && strlen( $val ) >= 88) {
$data[$key] = Security::rijndael( base64_decode( $val ), Configure::read( 'Security.cipherSeed' ), 'decrypt' );
}
}
//My attempt at hacking it back together
if(array_key_exists('first_name', $data)) {
$data['name'] = $data['first_name'] ." ". $data['last_name'];
}
return $data;
}
/*AssignedShift.php*/
public function afterFind($results, $primary = false) {
return $this->_afterFind($results, $primary);
}
Both models were created from the console - User has been modified but I haven't touched the relationships, and AssignedShift is completely untouched. Any ideas? Thanks in advance.
Related
I´ve got a function to build dynamically the object from the database.
My class extends a DBModel Class with a build function :
/* Function to setup the object dynamically from database */
protected function build(){
global $db;
if( !empty( $this->query ) ){
$data_from_db = $db->raw( $this->query );
if( !empty( $data_from_db ) ){
foreach ( $data_from_db as $property => $value ){
$class = get_called_class();
if( property_exists( $class, $property ) ){
$rp = new ReflectionProperty( $class, $property);
if( isset( $rp ) && $rp->getType() ){
// print_r($rp->getType()->getName() );
$this->{$property} = $value;
}
}
}
}
}
}
I´m trying to detect if the property is an Enum, otherwise I got this error :
Fatal error: Uncaught TypeError: Cannot assign string to property MyClass::$myEnumProperty of type MyEnumNameType
For the moment I can get MyEnumNameType with $rp->getType()->getName() but I don´t manage to check if MyEnumNameType is an Enum in order to set the value as Enum and not as a string which makes an error.
Someone knows the way to do this ?
I can think of two ways to do this
1:
var_dump($this->{$property} instanceof \UnitEnum );
2:
if (is_object($this->{$property})) {
$rc = new ReflectionClass($this->{$property});
var_dump($rc->isEnum());
}
My solution based on #IMSoP answer and this question, basically is based on enum_exists() :
protected function build(){
global $db;
if( !empty( $this->query ) ){
$data_from_db = $db->raw( $this->query );
if( !empty( $data_from_db ) ){
foreach ( $data_from_db as $property => $value ){
$class = get_called_class();
if( property_exists( $class, $property ) ){
$rp = new ReflectionProperty( $class, $property);
if( isset( $rp ) && enum_exists( $rp->getType()->getName() ) ){
$this->{$property} = call_user_func( [$rp->getType()->getName(), 'from'], $value );
}else{
$this->{$property} = $value;
}
}else{
$this->{$property} = $value;
}
}
}
}
}
Notice : $rc->isEnum() does not exist.
Here is a simple example of what I am trying to achieve:
I have a gravity form with different sections that will be shown conditionally by pre-populating dynamically. The thing is that I can't seem to populate them based on my ACF data (which are checkboxes as well).
If I put the values into the code it works like this:
add_filter( 'gform_pre_render_2', 'my_populate_checkbox' );
function my_populate_checkbox( $form ) {
foreach( $form['fields'] as &$field ) {
if( 11 === $field->id ) {
foreach( $field->choices as &$choice ) {
if( 'mychoice' === $choice['value'] || 'anotherchoice' === $choice['value'] ) {
$choice['isSelected'] = true;
}
}
}
}
return $form;
}
To get it to be populated dynamically I was trying something like this which didn't work (not that good with php):
add_filter( 'gform_pre_render_2', 'my_populate_checkbox' );
function my_populate_checkbox( $form ) {
foreach( $form['fields'] as &$field ) {
if( 11 === $field->id ) {
foreach( $field->choices as &$choice ) {
$addons = get_field('addons');
if( $addons === $choice['value'] ) {
$choice['isSelected'] = true;
}
}
}
}
return $form;
}
It's not working and I know I am missing something here but can't figure out what it is:/ Any help or pointers would be highly appreciated! I tried keeping it precise but if any more information is required please let me know and I will update the post accordingly.
Figured it out with some help:) In case anybody needs this functionality, here is how it works:
add_filter( 'gform_pre_render_2', 'my_populate_checkbox' );
function my_populate_checkbox( $form ) {
global $post;
$adfields = get_field( 'addons', get_the_ID() );
foreach( $form['fields'] as &$field ) {
if( 11 === $field->id ) {
foreach( $field->choices as &$choice ) {
if( in_array( $choice['value'] ,$adfields )) {
$choice['isSelected'] = true;
}
}
}
}
return $form;
}
I'm trying to get a PHP Code to work in order to make a Database query within a Wordpress database table. The results (all distinct values of one specific column) should be put out within an HTML list. I want to be able to place the output everywhere in my content, so it should be accessable via shortcode.
Here's what I got so far. This code does not produce any errors in wordpress or the console, but it also doesn't do the trick... Nothing appears at the desired place.
class my_Shortcode {
var $echo;
function __construct() {
add_shortcode( 'my_plugin', array( $this, 'shortcode' ) );
}
function shortcode( $atts ) {
global $wpdb;
$table = isset( $atts['table'] ) ? $atts['table'] : false;
$column = isset( $atts['column'] ) ? $atts['column'] : false;
$listDisplay = isset( $atts['listDisplay'] ) ? $atts['listDisplay'] : false;
if ( $listDisplay == true ) {
if ( false != $table && false != $column ) {
$this->echo = "";
$results = $wpdb->get_results(
prepare('SELECT DISTINCT ' . $column . ' FROM ' . $table)
);
$this->echo .= "<div class=\"list\"><ul>";
foreach ($results as $result) {
$this->echo .= "<li>$result</li>\n";
}
$this->echo .= "</ul></div>";
return $this->echo;
}
}
}
}
I'm glad about any suggestions!
Do you want likve this?
<?php
echo do_shortcode("[my_plugin table='wp_posts' column=id]");
?>
class my_Shortcode {
var $echo;
function __construct() {
add_shortcode( 'my_plugin', array( $this, 'shortcode' ) );
}
function shortcode( $atts ) {
global $wpdb;
$table = isset( $atts['table'] ) ? $atts['table'] : false;
$column = isset( $atts['column'] ) ? $atts['column'] : false;
$listDisplay = isset( $atts['listDisplay'] ) ? $atts['listDisplay'] : true;
if ( $listDisplay == true ) {
if ( false != $table && false != $column ) {
$this->echo = "";
$results = $wpdb->get_results("SELECT DISTINCT $column FROM $table ",ARRAY_A);
$this->echo .= "<div class=\"list\"><ul>";
foreach ($results as $key => $result) {
$keys = array_keys( $result);
$this->echo .= '<li>'.$result[ $keys[0] ].'</li>\n';
}
$this->echo .= "</ul></div>";
return $this->echo;
}
}
}
}
$test = new my_Shortcode();
I've just upgraded my local WooCommerce website to 3.0. Everything works perfectly as normal, but I've noticed with debugging turned on that I'm getting hundreds of the following notices:
[05-Apr-2017 12:25:00 UTC] PHP Notice: id was called <strong>incorrectly</strong>. Order properties should not be accessed directly. Please see Debugging in WordPress for more information. (This message was added in version 3.0.) in C:\xampp\htdocs\dev\wp-includes\functions.php on line 4137
So it looks like WooCommerce are pulling back being able to directly call order data. One example this code is being triggered by is this function in my functions.php file:
function eden_woocommerce_order_number($original, $order)
{
return 'EDN-' . str_pad($order->id, 10, 0, STR_PAD_LEFT);
}
This function simply adds "EDN" to the start of the order ID and pads it by 10 characters, but WooCommerce doesn't like how I'm calling $order - what would be the best way to rewrite such a function that 3.0 is happy with?
it says "id was called incorrectly. Order properties should not be accessed directly."
Try $order->get_id()
Maybe its helpful for others too. Here's the some stuff regarding to all the functions of directly accessed values through the magic function.
This function is from Woocommerce 3.0
if ( 'completed_date' === $key ) {
return $this->get_date_completed() ? gmdate( 'Y-m-d H:i:s', $this->get_date_completed()->getOffsetTimestamp() ) : '';
} elseif ( 'paid_date' === $key ) {
return $this->get_date_paid() ? gmdate( 'Y-m-d H:i:s', $this->get_date_paid()->getOffsetTimestamp() ) : '';
} elseif ( 'modified_date' === $key ) {
return $this->get_date_modified() ? gmdate( 'Y-m-d H:i:s', $this->get_date_modified()->getOffsetTimestamp() ) : '';
} elseif ( 'order_date' === $key ) {
return $this->get_date_created() ? gmdate( 'Y-m-d H:i:s', $this->get_date_created()->getOffsetTimestamp() ) : '';
} elseif ( 'id' === $key ) {
return $this->get_id();
} elseif ( 'post' === $key ) {
return get_post( $this->get_id() );
} elseif ( 'status' === $key ) {
return $this->get_status();
} elseif ( 'post_status' === $key ) {
return get_post_status( $this->get_id() );
} elseif ( 'customer_message' === $key || 'customer_note' === $key ) {
return $this->get_customer_note();
} elseif ( in_array( $key, array( 'user_id', 'customer_user' ) ) ) {
return $this->get_customer_id();
} elseif ( 'tax_display_cart' === $key ) {
return get_option( 'woocommerce_tax_display_cart' );
} elseif ( 'display_totals_ex_tax' === $key ) {
return 'excl' === get_option( 'woocommerce_tax_display_cart' );
} elseif ( 'display_cart_ex_tax' === $key ) {
return 'excl' === get_option( 'woocommerce_tax_display_cart' );
} elseif ( 'cart_discount' === $key ) {
return $this->get_total_discount();
} elseif ( 'cart_discount_tax' === $key ) {
return $this->get_discount_tax();
} elseif ( 'order_tax' === $key ) {
return $this->get_cart_tax();
} elseif ( 'order_shipping_tax' === $key ) {
return $this->get_shipping_tax();
} elseif ( 'order_shipping' === $key ) {
return $this->get_shipping_total();
} elseif ( 'order_total' === $key ) {
return $this->get_total();
} elseif ( 'order_type' === $key ) {
return $this->get_type();
} elseif ( 'order_currency' === $key ) {
return $this->get_currency();
} elseif ( 'order_version' === $key ) {
return $this->get_version();
} elseif ( is_callable( array( $this, "get_{$key}" ) ) ) {
return $this->{"get_{$key}"}();
} else {
return get_post_meta( $this->get_id(), '_' . $key, true );
}
You should call the woo get function. add get_ ()
For example, change:
$order->status to $order->get_status()
In my theme, there's custom page for the login. Login function at functions.php is like this
function log_in($username, $password) {
$user = parse_user($username);
$username = $username;
$password = $password;
if(isEmptyString($username)) return new WP_Error('username', 'required');
if(isEmptyString($password)) return new WP_Error('password', "required");
if(!wp_check_password( $password, $user->user_pass ) ) return new WP_Error('wrong_password', "wrong");
wp_set_auth_cookie($user->ID, $remember);
wp_login($username, $password);
redirect_profile();
}
function parse_user($info = null, $return = 'object') {
if ( is_null( $info ) ) {
global $current_user;
if ( empty( $current_user->ID ) ) return null;
$info = get_userdata( $current_user->ID );
}
elseif ( empty( $info ) ) {
return null;
}
if( $return == 'ID' ) {
if ( is_object( $info ) ) return $info->ID;
if ( is_numeric( $info ) ) return $info;
}
elseif( $return == 'object' ) {
if ( is_object( $info ) && $info->ID) return $info;
if ( is_object( $info )) return get_userdata( $info->ID );
if ( is_numeric( $info ) ) return get_userdata( $info );
if ( is_string( $info ) ) return get_userdatabylogin( $info );
}
else {
return null;
}
}
I want to add remember me checkbox for user to logged in all the time until they logout. How can i add this ? Please kindly help me out. Thank you.
"remember me" buttons are generally just a simple tweak to the cookie settings internally. Instead of a session cookie that gets deleted when the browser is exitted, a "remember me" login cookie gets some future expiration point (a day, a month, a year, etc...) so it'll persist after the browser's closed.
In pseudo-code, you'd have:
if (form_value('remember_me') == 'yes) {
set_long_term_cookie();
} else {
set_session_cookie();
}
"Add a login form on your WordPress Theme" (including remember me functionality):
http://www.wprecipes.com/add-a-login-form-on-your-wordpress-theme
Also: http://www.problogdesign.com/how-to/how-to-create-a-wordpress-login-form-overlay/
etc...