Wordpress pods framework - importing custom settings pages with php - php

I would like to import the pods settings using the functions.php file in my theme I have a json file exported from pods UI
function import_pods_package($package_data) {
// Check if Pods is active
if ( !function_exists( 'pods' ) ) {
return new WP_Error( 'pods_not_active', 'Pods plugin is not active' );
}
// Import the package
var_dump(json_decode($package_data));
$import = pods_api()->import( $package_data,);
// Return the result
if ( false === $import ) {
return new WP_Error( 'pods_import_failed', 'Failed to import Pods package' );
} else {
return true;
}
}
import_pods_package(get_template_directory_uri().'/general.json');
I tried this, but result is:: Warning: Invalid argument supplied for foreach() in C:\laragon\www\wordpress\test\wordpress\wp-content\plugins\pods\classes\PodsAPI.php on line **10668
i also tried to convert json file to csv and result is same.
If I have provided too little information, please let me know what else is needed

For the current state of the import(...) function in PodsAPI.php see https://github.com/pods-framework/pods/blob/main/classes/PodsAPI.php
/**
* Import data from an array or a CSV file.
*
* #param mixed $import_data PHP associative array or CSV input
* #param bool $numeric_mode Use IDs instead of the name field when matching
* #param string $format Format of import data, options are php or csv
*
* #return array IDs of imported items
*
* #since 1.7.1
* #todo This needs some love and use of table_info etc for relationships
*/
public function import( $import_data, $numeric_mode = false, $format = null ) {
// ... Doing something ...
// If the $import_data is a CSV, then parse it
if ( 'csv' === $format && ! is_array( $import_data ) ) {
$data = pods_migrate( 'sv', ',' )->parse( $import_data );
$import_data = $data['items'];
}
// ... Doing something ...
// Gets default valid POD fields
$fields = pods_config_merge_fields( $pod['fields'], $pod['object_fields'] );
// ... Doing something ...
// Loops through your $import_data
foreach ( $import_data as $key => $data_row ) {
$data = array();
// Loops through default valid POD fields and try to find an equivalent filed in your $import_data
foreach ( $fields as $field_name => $field_data ) {
// If there is not an equivalent filed in your $import_data, jump into the next field
if ( ! isset( $data_row[ $field_name ] ) && ! isset( $data_row[ $field_data['label'] ] ) ) {
continue;
}
// If there is an equivalent filed in your $import_data, apply its value to the current POD configuration
// ... Doing something ...
}
}
// Return the ID numbers of those valid fields which have been found in your $import_data
return $ids;
}
Your problem starts with the line 10668:
Clearly there is something wrong with the $fields variable. This variable contains the current configuration of your POD fields.
You can try to var_dump it to see what's wrong with it:
Go to PodsAPI.php and create a new function for testing purposes:
public function myTest() {
/**
* #var $wpdb wpdb
*/
global $wpdb;
pods_query( "SET NAMES utf8" );
pods_query( "SET CHARACTER SET utf8" );
if ( ! empty( $this->pod_data ) ) {
$pod = $this->pod_data;
} elseif ( ! empty( $this->pod ) ) {
$pod = $this->load_pod( [ 'name' => $this->pod ], false );
}
if ( false === $pod ) {
return pods_error( __( 'Pod not found', 'pods' ), $this );
}
$pod_name = $pod['name'];
$fields = pods_config_merge_fields( $pod['fields'], $pod['object_fields'] );
return $fields;
}
Go back to functions.php and var_dump the $fields variable:
function import_pods_package($package_data) {
// Check if Pods is active
if ( !function_exists( 'pods' ) ) {
return new WP_Error( 'pods_not_active', 'Pods plugin is not active' );
}
// Prints out the current POD fields configuration
$fields = pods_api()->myTest();
var_dump($fields);
// ...
}

Related

Push Elements into an array inside a class in wordpress

i am trying to make a plugin through Worpress, i have in the frontend a list of generated plugins
like so Plugins
what i am trying to do is to get these plugins to be stored into an array inside the class and be printed or processed inside any function or a callback if i clicked submit. and here is the code.
class Example {
private static $init_core_plugins = array();
private static function handle_post() {
$save_settings = filter_input( INPUT_POST, 'save_settings' );
if ( !is_null( $save_settings ) && check_admin_referer( 'save-settings' ) ) {
self::save_settings();
self::refresh_page();
}
}
private static function save_settings() {
$core_plugins = filter_input( INPUT_POST, 'coreplugins', FILTER_DEFAULT, FILTER_REQUIRE_ARRAY );
if ( empty( $core_plugins ) ) {
$core_plugins = [];
}
self::$init_core_plugins = array_merge( $core_plugins, self::$init_core_plugins );
// it shows here that it holds the correct selected plugins
echo "<pre>";
var_dump (self::$init_core_plugins);
echo "</pre>";
update_option( 'core_plugins_settings', $core_plugins );
}
public static function admin_render_main_page(){
// it shows here that it is an empty array
echo "<pre>";
var_dump (self::$init_core_plugins);
echo "</pre>";
}
}
What i am facing is somehow simple problem but i can't figure out where is the problem, when i called the array inside var_dump() inside save_settings() it printed the selected plugins from the list normally, but the problem is when later i try to var_dump (self::$init_core_plugins) in any other function like in the admin_render_main_page(), it returns as empty array, and the passed data through the save_settings() doesn't seem to be stored in the array.

Wordpress Error Elementor render_by_mode() compatibility with theme plugin

I have a website that uses a theme that is not updated.
I can't convince my client to change the current theme but it has a compatibility problem between a theme plugin and elementor, the error that I get is:
Fatal Error: Uncaught Error: Call to undefined method Nova_Elements\Modules\Slider\Widgets\Slider::render_by_mode() in Applications/XAMPP/xamppfiles/htdocs/thewebsite/wp-content/plugins/elementor/includes/base/widget-base.php:609
The issues happens with the new versions of elementor, the only one that seems to work without problems is the version 3.0.12 but it's too old and I would like to be able to update it.
The theme is "Reddot" if anyone wants to check, the plugin with the issue is called "Nova elements for Elementor".
Reading the error that I got my first thought was to check the file slider.php inside the nova-elements plugin and check where render_by_mode() is called.
Unfortunately that method is not used anywhere in that file and I don't really know where else to check, does anyone have some suggestion?
I also thought about checking at line 609 in the elementor plugin but if I make changes there I can't update it anyways so it will be the same problem.
Down here there is some of the code of the slider.php file, I don't know if it's enough or what else could be useful so please comment if you think I should add something to this question, I don't want to dump all the code here because it would be a waste of time so I tried to give you the code that I think could be the cause of this problem but I'm not really sure if I even really understood the problem.
Even if you can't solve my problem it would be helpful to know what to look for in this situation, it's the first time that I try to change a plugin so I don't really know where to start.
/**
* Generate setting json
*
* #return string
*/
public function generate_setting_json() {
$module_settings = $this->get_settings();
$settings = array(
'autoplay' => filter_var( $module_settings['slider_autoplay'], FILTER_VALIDATE_BOOLEAN ),
'autoplayDelay' => $module_settings['slider_autoplay_delay'],
'autoplayHover' => $module_settings['slide_autoplay_on_hover'],
'loop' => filter_var( $module_settings['slider_loop'], FILTER_VALIDATE_BOOLEAN ),
'speed' => $module_settings['slide_duration'],
);
$settings = json_encode( $settings );
return sprintf( 'data-settings=\'%1$s\'', $settings );
}
/**
* [__loop_button_item description]
* #param array $keys [description]
* #param string $format [description]
* #return [type] [description]
*/
protected function __loop_button_item( $keys = array(), $format = '%s' ) {
$item = $this->__processed_item;
$params = [];
foreach ( $keys as $key => $value ) {
if ( ! array_key_exists( $value, $item ) ) {
return false;
}
if ( empty( $item[$value] ) ) {
return false;
}
$params[] = $item[ $value ];
}
return vsprintf( $format, $params );
}
/**
* [__loop_item_image_src description]
* #return [type] [description]
*/
protected function __loop_item_image_src( ) {
$item = $this->__processed_item;
$image = $item['item_image'];
if ( empty( $image['id'] ) ) {
return Utils::get_placeholder_image_src();
}
$slider_image_size = $this->get_settings_for_display( 'slider_image_size' );
$slider_image_size = ! empty( $slider_image_size ) ? $slider_image_size : 'full';
return wp_get_attachment_image_url( $image['id'], $slider_image_size, false );
}
/**
* [render description]
* #return [type] [description]
*/
protected function render() {
$this->__context = 'render';
$this->__open_wrap();
include $this->__get_global_template( 'index' );
$this->__close_wrap();
}
protected function _content_template() {}

How to prevent duplicate values being posted?

I have a code that posts details from a form that looks like this. Field that contains Ampang, Kuala Lumpur = area_slug
This form then goes into a controller that as a post function to save the values in a table. Below is the code in the post function:
if ( $this->outlet->locations->count() ) {
foreach ( $this->outlet->locations as $index => $location ) {
$area = Level2::find( $locations[ $index ][ 'area_id' ] );
$area_slug = ( $area ? $area->slug : '' );
$shipping_fee_value = (float)$locations[ $index ][ 'shipping_fee_value' ];
// two type of conditional checks
// $shipping_fee_allow_negotiate = !empty( $location[ 'shipping_fee_allow_negotiate' ] );
if ( !empty( $locations[ $index ][ 'shipping_fee_allow_negotiate' ] ) ) {
$shipping_fee_allow_negotiate = 1;
} else {
$shipping_fee_allow_negotiate = 0;
}
/**
* Update each location belongs to Outlet
* Laravel Model Insert
* #see https://laravel.com/docs/8.x/eloquent#updates
*/
$location->area_slug = $area_slug;
$location->shipping_fee_value = $shipping_fee_value;
$location->shipping_fee_allow_negotiate = $shipping_fee_allow_negotiate;
$location->update();
}
} else {
foreach ( $locations as $location ) {
$area = Level2::find( $location[ 'area_id' ] );
$area_slug = ( $area ? $area->slug : '' );
$shipping_fee_value = (float)$location[ 'shipping_fee_value' ];
// two type of conditional checks
// $shipping_fee_allow_negotiate = !empty( $location[ 'shipping_fee_allow_negotiate' ] );
if ( !empty( $location[ 'shipping_fee_allow_negotiate' ] ) ) {
$shipping_fee_allow_negotiate = 1;
} else {
$shipping_fee_allow_negotiate = 0;
}
/**
* Create Location and related it to Outlet with `outlet_id`
* Laravel Model Insert
* #see https://laravel.com/docs/8.x/eloquent#inserts
*/
$location = new Location();
$location->outlet_id = $this->outlet->id;
$location->area_slug = $area_slug;
$location->shipping_fee_value = $shipping_fee_value;
$location->shipping_fee_allow_negotiate = $shipping_fee_allow_negotiate;
$location->save();
}
}
So what I'm trying to achieve is to prevent the same area_slug being posted eg. Ampang, Kuala Lumpur in both Location 1 and Location 2 respective fields. I have the idea of getting the previous area_slug but I'm not sure how to do so. If there are any unclear details do comment.
If you're using Laravel's validation, you can use distinct to ensure uniqueness over all submitted locations:
$request->validate([
'*.location' => 'distinct',
]);
I suggest you the following to have a good quality software :
Create a separate request Validation object called ModelStore with the following command :
php artisan make:request ModelStore
use this created as a parameter of your controller store function. like following
public function store(ModelStore $request)
in this ModelStore class implement 2 more function (there is 2 created by default for error code and message)
public function rules()
{
return [
'request_field' => ['LaravelValidation|anotherLaravelValidation']
];
}
//In this function you can put all your if else validations and returned a validation array
public function all($keys = null)
{
$data = parent::all($keys);
$data['one_field'] = affectValue;
return $data;
}
finaly in your controller store function start with this line to have the data array
$validated_data = $request->validated();
And then you have your data validated and cleaned. in the controller you keep only the logic and not validation.
To answer your initial question :
if you want to have a complete unique slug field than you simply implement it in the rules with the distinct or unique laravel validation.
Good luck
when you creating migration set table field as unique
$table->unique('email');
then you searching use distinct for query
return DB::table('teat_table')
->select('teat_table.*')
->distinct()
->get();

PHP Helper class to generate hash key from an array to be passed on to url

Helper Class to generate a unique key from the values of an array.
I have a home page search form where user selects different option to go next page. If I save the search in session User cannot make multiple orders be opening in a new tab.The only solution is to pass the search fields in the url. Since there is a limitation of the url length . I want to generate a hash value of the search data and pass it on to the url. Is there a better way to generate the hash value.
Only simple solution I have found is woocommerce cart key generation which uses md5 to generate the key.
class HashKey extends Object
{
public $model;
public $hashkey;
public function __construct($model)
{
$attributes = $model->getAttributes();
if ( is_array( $attributes ) && ! empty( $attributes ) ) {
$hashkey = '';
foreach ( $attributes as $key => $value ) {
if ( is_array( $value ) ) $value = http_build_query( $value );
$hashkey .= trim($key) . trim($value);
}
$id_parts[] = $hashkey;
}
$this->hashkey = md5( implode( '_', $id_parts ) );
}
/**
* String magic method
* #return string the DB expression
*/
public function __toString()
{
return $this->hashkey;
}
}

PHP Immutable Object Efficiencies

I've been working on an immutable object for use in PHP. One can do this by adapting a singleton pattern and playing around with the magic methods easily enough, but I have a couple of specific needs here.
1. Under no circumstances is a reference to a contained value to be returned.
2. If the contained data is an array (most likely a big 'ol tree loaded form json_decode()), then one must be able to search for a key using a search string
e.g.:
$thing = $foo->get( 'go.get.the.thingy.at.this.level' );
...which would return:
$foo->_data['go']['get']['the']['thingy']['at']['this']['level']
3. When walking down a contained array looking for keys, references are used -- and not copies.
This means that I will want to avoid the use of a foreach() call if it at all possible. If you don't understand what I mean (or understand why this is a concern), in PHP:
foreach() does not work on the object you are iterating.
foreach() works on a copy of the object being iterated.
My Question
I've got something of a shell here (minor syntax problems aside), but I'd like to see if this can be made any more efficient, or if there are better tricks at accomplishing the same task
class ProperlyProtectedObject {
// PUBLIC STUFF
/// Initializes the singelton and returns a reference -- or cowardly returns a null.
public static function init( $value ) {
if( true === empty( self::$_self ) ) { // empty returns true if 0, false, null, or not set
if( false === isset( $value ) ) { // isset returns true if not set or null.
return null; // ...you idjit!
}
self::$_data = new ProperlyProtectedObject( $value );
}
return & self::$_self;
}
/// invoke ( php > =5.3 ): default
public function __invoke( $var ) {
return $this->get( $var );
}
public function __call( $f, $args ) {
return $this->get( $args );
}
public function __callStatic( $f, $args ) {
return null; // idjit.
}
/// get: NEAT TRICK:
/// if you know that you are storing an array here, then you can pass a dot syntax
/// string (e.g.: foo.bar.soemthing_else.foo.0 ) and
/// -- provided that your keys don't contain dots (:-P) --you can get the value of a
/// nested array key!
/// \return <Mixed> Any value **except** NULL is the value at the depth you are looking for.
/// \return NULL this means that you.have.a.BAD.Key.string.SomeWhere
public function get( $val ) {
$copyOfThing = null;
if( true === is_array( self::$_data ) ) {
if( true === is_string( $val ) ) {
$keys = explode( '.', $val );
if( 0 < count( $keys ) {
$copyOfThing = walk( self::$_data, $keys );
}
}
}
else {
$copyOfThing = self::$_data;
}
return $copyOfThing;
}
/// set: DOES NOTHING. This object is meant to take an act of congress to delete data.
public function __set( $objProp, $value ) {
// do nothing.
// echo '<pre>DIE IN A FIRE!!!! ' . var_export( $objProp, true ) . '</pre>';
}
/// isset:
public function __isset( $objProp ) {
return ( null !== $this->get( $objProp ) ) ? true : false;
}
/// unset: DOES NOTHING.This object is meant to take an act of congress to delete data
public function __unset( $objProp ) {
// do nothing.
// echo '<pre>DIE IN A FIRE!!!! ' . var_export( $objProp, true ) . '</pre>';
}
//
// PRIVATE STUFF
//
private $_self; ///< the singleton instance
private $_data = Array(); ///< this is the data. Just the data, and only the data.
/// CTOR: Singleton!
private function __construct( $value ) {
self::$_data = $value;
}
/// CCTOR: Singletons have have no need to copy themselves
private function __clone() {
// do nothing
}
/// fetches the value from WAAAY down in the array
private function walk( Array &$arr, Array $keystack ) {
$key = array_pop( $keystack );
if( false === array_key_exists( $key, $arr ) ) {
return null;
}
if( 0 count( $keystack ) ) {
return $arr[$key];
}
else {
return walk( $arr[$key], $keystack );
}
}
}

Categories