wordpress make changes to post api - php

We are using wordpress for blogs (hosted via Godaddy). I am not a wordpress developer and hence this basic question. We have the wordpress post api like blog.domainname.com/wp-json/wp/v2/posts. This returns a json object of most of the fields. Now i have added a custom field to be returned with this object. i have seen lot of videos and study on what changes that needs to be done especially the one here.
https://developer.wordpress.org/rest-api/extending-the-rest-api/modifying-responses/
My Question is - Where do I make these changes? What file do I need add these changes? I am using WP as an admin. I installed a File Explorer plugin and I am able to see three main folders - wp-admin, wp-content, wp-includes.
Is there a particular file i need to make changes? Based on my learning - i wrote the following snippet. not sure where to add this :(
function addCustomField_register_fields() {
register_rest_field('post',
'custom_Field_name',
array(
'get_callback' =>'get_custom_field',
'update_callback' => null,
'schema' => null
));
}
function get_custom_field($object, $field_name , $request) {
return get_post('custom_field');
}
add_action('rest_api_init', 'addCustomField_register_fields');
Also would appreciate if you can let me know if my method is correct.

Typically theme customisations are added to the functions.php file in the root directory of your active theme.
As for your code, what are you trying to do? Your callback in particular doesn't look like it will work. get_post() loads a WordPress post by ID. 'custom_field' isn't a valid post ID, so this will always fail.

Related

Make custom post type that is rendered by plugin not queryable

I'm using the WooCommerce plugin and with it comes the products post type.
For my site, I've created actual pages for my products, so I don't need /products to exist.
Usually, if I had created the post type, I would add publicly_queryable' => false to make sure the /products url didn't exist, but this post type is created by WooCommerce so unsure how to go about it? Or if it has any implications.
Trying to remove these unnecessary pages from the sitemap.
So this answer came from this post over at the WordPress Stack Exchange site.
Add this to your theme's functions.php file and give it a try. I tested it on a clean WP install with just WooCommerce installed, and it seems to work as intended.
function change_wp_object() {
if(post_type_exists('product')){
$object = get_post_type_object('product');
$object->publicly_queryable = false;
}
}
add_action('init','change_wp_object');
I added a check to see if the 'product' post type exists (please note that your question says the post type is called 'products' but it is actually 'product'). Adding that if/condition helps eliminate errors thrown if WooCommerce wasn't installed or activated.
If you want to exclude post_type from Yoast SEO sitemap - try this code
function sitemap_exclude_post_type( $excluded, $post_type ) {
return $post_type === 'product';
}
add_filter( 'wpseo_sitemap_exclude_post_type', 'sitemap_exclude_post_type', 10, 2 );

Where do I POST and store simple JSON data on a wordpress database using the REST API?

I am looking for some insight on where to store user JSON data on Wordpress via the REST API.
I am working on a single-page-application website that will allow users to create a watchlist of movies and click whether they liked the movie. I am using the Wordpress REST API and want to be able to store the users likes and watchlists on the Wordpress database.
For example, using the list of liked movies, I created the below custom end point in my functions.php file:
add_action('rest_api_init','add_user_likes');
function add_user_likes(){
register_rest_route(
'v1/user_likes','/(?P<id>\d+)',[[
'methods'=> 'GET',
'callback'=>'get_user_likes'
],
[
'methods'=> 'POST',
'callback'=>'post_user_likes'
]]);
};
I am attempting to POST from the front end a simple object holding post_id and post_title.
Here are is my callback for the GET method:
function get_user_likes(){
return array(
"post_id"=>$post_id,
"post_title"=>$post_title
);
}
And for the POST method:
function post_user_likes(WP_REST_Request $req){
$body = $req->get_json_params();
$post_title = $body->post_title;
$post_id = $body->post_id;
return [
$body
];
};
Using Firefox's RESTer plugin, I am getting status 200 for both methods, but none of my POST attempts are actually saving.
I've spent a couple of days researching how to write the callbacks for each method with no luck. It occurred to me that I am not actually assigning the user data a place to be saved in Wordpress.
After doing some research, I haven't really found an answer on where this JSON data would best be stored.
If someone could provide some insight on where and how to store user JSON data on WP, that would be great. Also, if anyone could provide help on writing callbacks to do this, that would be great.

Moodle plugin : check if admin + add link to plugin in administration

I'm new to moodle plugin development and am trying to create a plugin that displays a page to the admin where I can add my on php code.
In brief, what I want the plugin to do I have already achieved in a standard php file that I upload to the moodle root. From here you can call the file e.g. yourdomain.co.uk/moodlelocation/myfile.php and it will run as expected.
The problem with this is it isn't secure since anyone can load the myfile.php and in turn run the scripts on the page. It also means any one else using this script (it will be given away for free when complete) would need to FTP into their hosting and upload two php files to their moodle install.
Due to this, I thought a plugin (a very very basic plugin) may be the best solution. They could then load the page in the admin via the "site administration". e.g. site administration > Development > MyPlugin. I am assuming I could then also restrict the plugin's main page to admins only (??).
So to recap, I can create a php page that has my script all rocking and rolling BUT I need to make this into a plugin.
I did some reading and I think a "local" plugin was the easiest way to go (??).
I have managed to get the local plugin up and running using the below in local/webguides/inex.php :
<?php
// Standard config file and local library.
require_once(__DIR__ . '/../../config.php');
// Setting up the page.
$PAGE->set_context(context_system::instance());
$PAGE->set_pagelayout('standard');
$PAGE->set_title("webguides");
$PAGE->set_heading("webguides");
$PAGE->set_url(new moodle_url('/local/webguides/index.php'));
// Ouput the page header.
echo $OUTPUT->header();
echo 'MY php CODE here etc';
?>
This works fine but with two problems:
Anyone can access it via http://domain/local/webguides/index.php
There is no link to it in the site administration (so the user would need to type the URL in).
Can anyone shed any light how I would achieve the two steps above?
Thanks in advance
p.s. ideally I'd like to keep the plugin to as few files as possible so if the required code could be added to the local/webguides/index.php file it would be preferred.
You need to create a capability, then require that capability before displaying the page.
First, have a look at local/readme.txt - this gives an overview of the files needed for a local plugin.
Or read the documentation at https://docs.moodle.org/dev/Local_plugins
Also have a look at existing local plugins so you can see how they are created - https://moodle.org/plugins/?q=type:local
At a bare minimum, you need
local/webguides/db/access.php - this will have the capability
local/webguides/lang/en/local_webguides.php
local/webguides/version.php
Plus your index file
local/webguides/index.php
In the db/access.php file have something like
defined('MOODLE_INTERNAL') || die();
$capabilities = array(
'local/webguides:view' => array(
'captype' => 'read',
'contextlevel' => CONTEXT_SYSTEM,
'archetypes' => array(
),
),
);
You might also need 'riskbitmask' => RISK_XXX depending on if there are any risks in you code. Such as RISK_CONFIG, RISK_PERSONAL, etc.
In lang/en/local_webguides.php have something like
defined('MOODLE_INTERNAL') || die();
$string['pluginname'] = 'Webguides';
$string['webguides:view'] = 'Able to view webguids';
In version.php have something like
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2020051901; // The current plugin version (Date: YYYYMMDDXX)
$plugin->requires = 2015051109; // Requires this Moodle version.
$plugin->component = 'local_webguides'; // Full name of the plugin (used for diagnostics).
Replace 2015051109 with the version of Moodle you are using - this will be in version.php in the root folder.
Then in your index.php file use this near the top.
require_capability('local/webguides:view', context_system::instance());
So only users with that capability will have access to the page.
EDIT:
You can add a link via settings.php using something like
defined('MOODLE_INTERNAL') || die;
if ($hassiteconfig) {
$page = new admin_externalpage(
'local_webguides',
get_string('pluginname', 'local_webguides'),
new moodle_url('/local/webguides/index.php'),
'local/webguides:view'
);
$ADMIN->add('localplugins', $page);
}
Then in your index page ad this
require_once($CFG->libdir.'/adminlib.php');
and remove require_login() and require_capability() and replace with
admin_externalpage_setup('local_webguides');

Editing serialized data WordPress dashboard

I just inherited a custom plugin that takes Formstack submissions and creates WordPress posts from them. The posts are created fine, however the form contents are stored as serialized data in post_content.
I am tasked with enabling these posts to be edited within the WP Dashboard. Currently when you click on a post title, you are presented with a page that just shows the data; no capability to edit the data.
Enabling the editor controls within "supports" in the functions.php file gives me the editor with the serialized data just dumped in the editor.
I have never had to setup a custom edit page for a specific post type in WP. Is there someone out there who can direct me so a site that explains this? I'm running in circles.
You can filter the content before it is presented in the admin editing screen.
function my_filter_function_name( $content, $post_id ) {
if(get_post_type($post_id) == 'the_post_type_in_question'){
$serialized_content = $content;
$content_array = unserialize($serialized_content);
// do something with this array to put it in the format you want
// .....
$content = $new_formatted_content;
}
return $content;
}
add_filter( 'content_edit_pre', 'my_filter_function_name', 10, 2 );
But, that doesn't seem like it's going to be of much use to you.
In your situation, I suggest you take the time to write a script to convert all those posts so that everything is stored as post meta. (create the custom fields, first).
If your theme isn't built on any framework, then I think the quickest way to create a custom field is to use the Advanced Custom Fields plugin.
Then, once you know the meta_keys, you can write that script. E.g.
$posts = get_posts('post_type'=>'the_post_type','posts_per_page'=> -1);
foreach($posts as $post){
$content_array = unserialize($post->post_content);
// how you do the next bit will depend on whether or not this is an associative array. I'm going to assume it is (because it's a little easier :) )
foreach($content_array as $meta_key=>$meta_value){
update_post_meta($post->ID, $meta_key, $meta_value);
}
// just put what you actually want as the post content back into the post content:
wp_update_post(array('ID'=>$post->ID,'post_content'=>$content_array['post_content'])); // assuming the key of the element you want to be the post content is 'post_content'
}
To run this script, you could simply create a temporary new page and then create a template file specifically for that page and put the above code into that file (then visit the page).
You need to modify the plugin so that the data is unserialized before modifying, then serialized before saving to DB...
Alternatively, try using WP's CORE functionality:
https://codex.wordpress.org/Function_Reference/maybe_serialize
https://codex.wordpress.org/Function_Reference/maybe_unserialize
https://codex.wordpress.org/Function_Reference/is_serialized
https://codex.wordpress.org/Function_Reference/is_serialized_string

How to modify data for a SugarCRM SubPanel using PHP?

Is there anyway to modify the content shown in a SugarCRM Subpanel without relying on Action Hooks?
Right now to edit content for a Subpanel field I have to use the hooks like this...
$hook_array['process_record']
And in the Class method that I assign the Hook to call I can then change a field in the Subpanel like this...
$bean->name = '<a href="/index.php?action=ajaxui#ajaxUILoc=index.php%3Fmodule%3Dproje_Web_Project_Tasks%26action%3DDetailView%26record%3D'
.$bean->id.'" rel="popover" data-content="'
.$bean->description.'" data-original-title="">'.$bean->name.'</a>';
The main and major problem we have with this method is it works great until you do either of these actions....
Add an item using the Quick Create form
Change a page using the Subpanel paging buttons
In either case, it reloads the Subpanel data without running this hook code on the data, so the result is pretty major as the Subpanel fields that you have edited are no longer edited and show up as normal.
Here is a basic example...this shows 2-3 fields that have been edited using the Hook method above...
Now after paging or quick-creating a new record in the Subpanel, it reloads the Subpanel data and does not apply the Hooked code so you can see the result looks like this...
I know that ListView has a much more reliable and flexible method for editing it's content using the get_list_view_data() method I am able to apply the same edits and have them work all the time!
So I am hoping there is a similar method to edit Subpanel data and have it always apply the edits to that data? From what I have seen in my research so far, the only solution that will work as expected all the time, is to make a completely new Custom Field Type!
I am really hoping that is not the ONLY way as that is a major pain to do that for each type of field that I need to edit in the Subpanels and just doesn't feel right when there are easy ways to edit everything else except SubPanel data.
Does anyone have any ideas, suggestions, tips, help, please do share with me on this matter as it is the main problem I have had since I started developing with SugarCRM in the past few months?
You can change the data by writing a custom query to get data for your subpanel.
So inside your bean (this case Contacts) do a functions:
function get_project_list() {
$query = "SELECT project, info, matching, column, names FROM projects WHERE contact_id = '" . $this->id . "' AND deleted = 0"
return $query;
}
and then in subpanel definition set the data source like this:
$layout_defs["Contacts"]["subpanel_setup"]['projects'] = array(
'order' => 10,
'sort_order' => 'desc',
'sort_by' => 'name',
'title_key' => 'LBL_PROJECTS_TITLE',
'subpanel_name' => 'contact_projects',
'module'=>'projects',
'get_subpanel_data' => 'function:get_project_list',
'function_parameters'=>array('type'=>'urgent'), // this is optional if you decide to sent parameters to the function if do this dont forget to define your function with function get_project_list($params)
'top_buttons' => array (... buttons that you need go here..),
);
Since sql is quite powerful you can modify your subpanel data any way you like, well more or less :)

Categories