I'am working on a sorter plugin for WordPress, which have Redux Framework installed to manage the options of every section. The plugin uses AJAX to get the ids of all the sections in the homepage of the website, then passes those values to the plugin main file to process in a function that stores the values in the current user meta. That works well, no problem here. The function looks like this:
add_action( 'wp_ajax_save_sections_ids', 'save_sections_ids_sorting_sections' );
function save_sections_ids_sorting_sections() {
//stuff here...
$user_ide = get_current_user_id(); //it works because it is inside a hook
update_user_meta($user_ide, "set-sections", $sections_ids);
die();
}
Then I have to get the stored values in user_meta to pass them to the Redux Field, so I wrote other function in the main file of the plugin. The function is this:
function get_the_db_sections_ids() {
$user_ide = 1; //This should be get_current_user_id() or something similar, but nothing works, not even globalizing $current_user and using get_currentuserinfo();
$sections_ids = get_user_meta($user_ide, "set-sections", true);
$sorter_field = array(
"section_id" => "basic",
'id' => 'homepage-sections',
'type' => 'sorter',
'title' => 'Control de secciones',
'desc' => 'Arrastra y suelta los bloques con los nombres de las secciones, tanto para ordenarlas verticalmente como para desactivarlas o activarlas.',
'compiler' => 'true',
'options' => array(
'enabled' => array(
),
'disabled' => $sections_ids
),
);
return $sorter_field;
}
As you notice in the comment in the function above, I have tried several ways, also require_once("/../../../wp-load.php"), but nothing happens. I tried do_action and add_actions, to create a hook, but those also use global variables, and for what I understand, the global variables do not work in functions with no hooks in plugins.
But I havent finished yet. The really tricky part is, I am calling an instance of Redux class inside the Redux config file (sample-config.php for the demo, I have a custom file, but it is the same).
The instance is Redux::setField($opt_name, get_the_db_sections_ids());
The problem this does not print anything if I call it from a function, or the function linked to the AJAX call.
As you can see, the second parameter of the instance is the function I wrote above that, and it works perfectly if I set $user_ide to 1, but I want the data stores in all admins user_meta, in case user 1 is erased, or whatever.
Is there a way to achieve what I want, or to store the data somewhere else and get it from there. I was thinking in creating a custom table in db, and use wpdb to retrieve the data, but I think I can't use wpdb either, because it will be the same problem.
I get the feeling I'm missing something very basic, but I can't get it. Please help.
This should help you out
global $current_user;
get_currentuserinfo();
$user_ide = $current_user->ID;
You'll have to declare a global variable $current_user, in order to use it.
Finally I found the solution to my problem. As I said, I couldn't get the current user id from the pligin if I tried outside an action hook or a filter hook, setting sessions and global variables didn't work, and functions hooked with WP normal hooks wouldn't set the Redux field. I reviewed the sample-config.php file inside the ReduxFramework/sample folder, and I found out some functions and hooks. One of them to set the entire section, but inside that section, you can set the field and it worked.
I eresed the Redux::setField instance, and did this in the sorter plugin main file:
add_filter('redux/options/' . $opt_name . '/sections', 'dynamic_section');
if ( ! function_exists( 'dynamic_section' ) ) {
function dynamic_section( $sections ) {
global $current_user;
get_currentuserinfo();
$sections[] = array(
'title' => __( 'Section via hook', 'redux-framework-demo' ),
'desc' => __( '<p class="description">This is a section created by adding a filter to the sections array. Can be used by child themes to add/remove sections from the options.</p>', 'redux-framework-demo' ),
'icon' => 'el el-paper-clip',
'fields' => array(get_the_db_sections_ids($current_user->ID))
);
return $sections;
}
} //I copied it from sample-config.php and added what's inside `"fields" =>` and the global.
Then I modified my array function like this:
function get_the_db_sections_ids($user_ide) { //Added the parameter
//Erase $user_ide = 1;
$sections_ids = get_user_meta($user_ide, "set-sections", true);
$sorter_field = array(
"section_id" => "basic",
'id' => 'homepage-sections',
'type' => 'sorter',
'title' => 'Control de secciones',
'desc' => 'Arrastra y suelta los bloques con los nombres de las secciones, tanto para ordenarlas verticalmente como para desactivarlas o activarlas.',
'compiler' => 'true',
'options' => array(
'enabled' => array(
),
'disabled' => $sections_ids
),
);
return $sorter_field;
}
And that's it, I hope this will help somebody. Redux is great but their documentation is very far from good, so, here's one little contribution for those using the framework. And thanks to the users who tried to help me.
Related
This is to create a custom RSS feed. I have a CPT called quotes with a Taxonomy called quote_category
I want all posts where quote_category = 'Dogs' which has ID = 115. This isn't working:
$postCount = 10; // The number of posts to show in the feed
$postType = 'quotes'; // post type to display in the feed
$catName = 'Dogs';
$posts = query_posts(array('post_type'=>$postType, 'quote_category'=>$catName, 'showposts' => $postCount));
Generally speaking the consensus is to avoid query_posts at all costs. The official documentation even backs this up:
Note: This function will completely override the main query and isn’t intended for use by plugins or themes. Its overly-simplistic approach to modifying the main query can be problematic and should be avoided wherever possible. In most cases, there are better, more performant options for modifying the main query such as via the ‘pre_get_posts’ action within WP_Query.
Instead, get_posts() will do everything that you want it to do. For your case, you just want to add on a tax_query with your information.
$posts = get_posts(
[
'post_type' => 'quotes',
'numberposts' => 10,
'tax_query' => [
[
'taxonomy' => 'quote_category',
'field' => 'name',
'terms' => 'Dogs',
],
],
]
)
The terms parameter also accepts an array if you need multiple:
'terms' => ['Dogs', 'Cats'],
Edit
If you are using get_template_part then you are probably also using the standard WordPress loop, too. That is actually one of the few times that you could use query_posts but I still personally just don't use it nor recommend it. In an ideal world, you'd probably use a filter just as pre_get_posts but I unfortunately I don't have time to write code to test that. You should be able to use the below code.
This code is an action that calls an anonymous function which adds a feed using another anonymous function as a callback. Your code does the exact same thing, however you are using named functions which is 100% fine, safe and common to do. I just personally prefer to keep my hooks and logic all together and not chase names down. Once again, totally personal preference.
If you still receive an internal error, make sure that both WordPress and PHP debugging is enabled so that you can see what the actual error is, and it is probably a little typo on my part.
add_action(
'init',
static function () {
add_feed(
'quotes',
static function () {
// Override the main query since the render functions wants to use the loop
global $wp_query;
$wp_query = new WP_Query(
[
'post_type' => 'quotes',
'post_count' => 10,
'tax_query' => [
[
'taxonomy' => 'quote_category',
'field' => 'name',
'terms' => 'Dogs',
],
],
]
);
get_template_part('rss', 'quotes');
}
);
}
);
I'm developing a prestashop module and I'm trying to show a category tree in my backoffice configuration page.
I'm trying to follow this instructions below but I don't know exactly where to add this code.
It should be inside main module's php? or inside a separate .php file and call it from the main one (don't know how to do it either).
As much time I'm spending trying to figure out, how to implement the code in the link above, the more I think I'm losing my time.
I see that "use" files, and this JS, " /admin-dev/themes/new-theme/js/components/form/choice-tree.js " are not in any prestashop folders.
Well, you should invest some time and learn Symfony since this is what you need to build backend modules for Prestashop 1.7.
As a pointer, you need to create a form class extending the CommonAbstractType, add a build form method. e.g. :
public function buildForm(FormBuilderInterface $builder, array $options)
{
$this->context = Context::getContext();
$parents = [
['id_category' => 2, 'name' => 'Home', 'children' => $this->getSubCategories(1, true, 2)]
];
$builder->add('category', CategoryChoiceTreeType::class, [
'choices_tree' => $parents,
'choice_value' => 'id_category',
'choice_children' => 'children',
'choice_label' => 'name',
'disabled_values' => $disabledCategories,
'label' => 'Choose a category'
])
then add methods for retrieving the data to populate the form fields.
Then use this class in your controller and display the form:
$form = $this->createForm(YourFormForm::class);
Also add a processForm to process data.
As mentioned, this is not a copy/paste situation you need to understand the Symfony workflow.
The only way that I found to "paint" the categorytree in my configuration page is adding this code to the inputs form array:
Can anyone tell me how to retrieve users selection data to my database?
It does not work as any other form field.
array(
'type' => 'categories',
'label' => $this->l('Destination Category'),
'desc' => $this->l('Select ONE Category'),
'name' => 'CATEGORY_CATEGORY_TO',
'tree' => [
// 'selected_categories' => [],
'disabled_categories' => null,
'use_search' => false,
'use_checkbox' => false,
'id' => 'id_category_tree',
],
'required' => true
),
Well, it is SOLVED!!!! Finally it was very simple, but you must get the correct info for you particular case.
#Robertino's answer might be the best implementation, I don't know, but it became impossible to solve for me,
I uses this code below, and called $categoryTree from the form input. This input must be type=> categories_select
Thanks for your time, and for the help of another post from this forum.
$root = Category::getRootCategory();
//Generating the tree
$tree = new HelperTreeCategories('categories_1'); //The string in param is the ID used by the generated tree
$tree->setUseCheckBox(false)
->setAttribute('is_category_filter', $root->id)
->setRootCategory($root->id)
->setSelectedCategories(array((int)Configuration::get('CATEGORY_1'))) //if you wanted to be pre-carged
->setInputName('CATEGORY_1'); //Set the name of input. The option "name" of $fields_form doesn't seem to work with "categories_select" type
$categoryTree = $tree->render();
And the Form:
array(
'type' => 'categories_select',
'label' => $this->l('Category'),
'desc' => $this->l('Select Category '),
'name' => 'CATEGORY_1', //No ho podem treure si no, no passa la variable al configuration
'category_tree' => $categoryTree, //This is the category_tree called in form.tpl
'required' => true
I asked this same question on the official forums but received no response. Not sure if anyone here is experienced with PrestaShop but here is my issue.
I need to add an extra field in the manufacturer edit/add tab, I was able to do this by overriding renderForm in AdminManufacturersController.php like this:
public function renderForm()
{
global $shopOptions;
$this->fields_form_override = array(
array(
'type' => 'checkbox',
'label' => 'Shop',
'name' => 'shop_select',
'desc' => 'Choose The Shops This Manufacturer Applies To',
'values' => array(
'query' => $shopOptions, >> comes from array filled by db query in __construct
'id' => 'id',
'name' => 'name'
),
),
);
return parent::renderForm();
}
This works and I am now trying to find the update and create functions for a manufacturer. When editing the product classes, you can easily spot set functions like setQuantity in StockAvailable.php.
I have ssh access to the server so I was able to dig deeper with grep, to no avail. It seems like it uses some sort of function to auto insert into the database whilst some classes use a plain old execute with a normal query.
Any ideas on where this could be found?
On Prestashop 1.6.x you do not need to amend any function for it to have CRUD functionalities. You just need to add it in :
RenderForm (like you already did)
Add the variable in the manufacturer class (Manufacturer.php) like public $shop_select;
Add it in the public static $definition array in the manufacturer class
Add the column in manufacturer or manufacturer_lang table depending on whether your field is a lang field.
Cheers :)
is it somehow possible to update a wordpress-plugin via another plugin with php code?
i tried something like this
$request = wp_remote_post(
'http://wordpress2/wp-admin/admin-ajax.php',
array(
'body' => array(
'plugin' => 'hello-dolly/hello.php',
'slug' => 'hello-dolly',
'action' => 'update-plugin',
'_ajax_nonce' => wp_create_nonce( 'nonce-test' ),
)
));
but this only leads in a 400 status...
I thought this kind of stuff would be easy in wordpress, dumb me! :-D
Found a solution:
after all plugins are loaded add a filter which define to auto-update plugins
add_action( 'plugins_loaded', array( CLASS, 'abpr_plugins_loaded' ), 1 );
public static function abpr_plugins_loaded(){
add_filter( 'auto_update_plugin', '__return_true');
}
the define some function which will be triggered from something, in my case it is an custom api-url which calls this:
public static function update_all_defined_plugins($data){
set_site_transient( 'update_plugins', '' );
wp_maybe_auto_update(); }
keep in mind that this is some bare stuff here without any code- & results-checking
I have a Problem with one node type and it's form. I want to alter it with an template file. I already did this with another node type on my drupal site and this worked, but it doesn't work for this second type.
So (as I did for the other node type) I placed this hook in my module:
function MY_MODULE_theme($existing, $type, $theme, $path) {
return array(
'FORM_ID' => array(
'arguments' => array(
'form' => NULL,
),
'render element' => 'form',
'template' => 'TYPE-node-form',
'path' => drupal_get_path('module', 'MY_MODULE'),
),
);
}
And also declared this function (in my module):
function template_preprocess_TYPE_node_form(&$variables) {
/* Some hide(elements) and stuff */
}
And of course, I created the file TYPE-node-form.tpl.php in the module directory
/* Something */
TEST
<?php if($form): ?>
<?php print drupal_render_children($form); ?>
<?php endif; ?>
/* Something more */
But it does not load this template ( I cannot see TEST and the other things). Also after multiply times of clearing cache and refreshing.
With DisplaySuite I was able to set a template in the backend (Administration » Structure » Content types » TYPE » Manage fields). But I want to have my own template file (and also not located in the sites/all/modules/ds/layout/.. folder). Deactivating DisplaySuite also does not do the trick.
I also looked tried to place the MY_THEME_theme() code into the template.php file of the administrator theme, but it also did not work.
Any suggestions? What can I do? Is there a way to find out which template is used or where it is overwritten? I have read that Themes overwrite modules templates declaration?!
If you are using D7, hook_theme implementations do not have 'arguments' key, but 'variables'.
Also in this case remove the 'arguments' or 'variables' key in order for the 'render element' to work. Hope this helps.
Final code:
function MY_MODULE_theme($existing, $type, $theme, $path) {
return array(
'FORM_ID' => array(
'render element' => 'form',
'template' => 'TYPE-node-form',
'path' => drupal_get_path('module', 'MY_MODULE'),
),
);
}