WpGraphQL: Creating Extensions - Having Issues - wordpress

Maybe I'm in over my head but I'm trying to create an extension for WpGraphQL to just gather the YITH WooCommerce Product Add-Ons info for each product but I've gotten to the point of banging my head against the desk in frustration. Is there a fairly easy way to just output the array into nodes? The following is what I have so far, currently I'm only getting one product with a set ID (later, hopefully it will get the one associated with that query). I can get a simple string output but I can't get it to output the array into nodes? What am I doing wrong? I commented out ideas I had for an output but it just usually results in an error or null. I do see the graphql_debug working and outputting $fields as an array though? Thanks!
register_graphql_object_type('MyNewType', [
'description' => __('Describe the Type and what it represents', 'replace-me'),
'fields' => [
'nodes' => [
'type' => 'String',
'description' => __('Describe what this field should be used for', 'replace-me'),
'fields' => [
'form_type' => [
'type' => 'String',
'description' => __('Describe what this field should be used for', 'replace-me'),
],
],
],
],
]);
register_graphql_field(
'Product',
'YITH_fields',
[
'type' => 'MyNewType',
'description' => __('Example field added to the Post Type', 'replace-with-your-textdomain'),
'resolve' => function (\WPGraphQL\Model\Post $post) {
global $wpdb;
$sql = "SELECT wp_live_yith_wapo_types.type, wp_live_yith_wapo_types.options FROM wp_live_yith_wapo_groups JOIN wp_live_yith_wapo_types on wp_live_yith_wapo_groups.id = wp_live_yith_wapo_types.group_id WHERE FIND_IN_SET(13, products_id)";
$results = $wpdb->get_results($sql);
if ($results) {
$array = array('nodes');
//$array = array();
foreach ($results as $result) {
$type = array('form_type' => $result->type);
$options = maybe_unserialize($result->options);
$result = array_merge($type, $options);
$array[] = $result;
}
//$array = wp_json_encode($array);
$fields = !empty($array) ? $array : null;
} else {
$fields = null;
}
graphql_debug($fields, ['type' => 'ARGS_BREAKPOINT']);
//return $fields['nodes'];
return $fields;
}
]
);

Probably it's good enough to return an array of Info 'records' (without embedding into nodes subfield - it would require some, own 'InfoList' type def.), then you need a type for single Info, like:
register_graphql_object_type('MyInfoItem', [
'description' => __('Describe the Type and what it represents', 'replace-me'),
'fields' => [
'form_type' => [
'type' => 'String',
'description' => __('Describe what this field should be used for', 'replace-me'),
],
// options field - list of some scalar or custom type
'options' => [
'type' => [ 'list_of' => 'String' ],
'description' => __('Describe what this field should be used for', 'replace-me'),
],
],
]);
extend Product with:
register_graphql_field(
'Product',
'YITH_fields',
[
'type' => [ 'list_of' => 'MyInfoItem' ],
'description' => __('Example field added to the Post Type', 'replace-with-your-textdomain'),
'resolve' => function (\WPGraphQL\Model\Post $post) {
// ...
return [
['form_type' => 'some_value'],
[
'form_type' => 'other_value',
'options' => ['opt_1', 'opt_2'],
],
];
Any, not trivial data 'nesting level' requires a separate type definition.
For more complex options 'records' you need to register another type - e.g. ids required for optional option selection.
If you don't want to explicitely express these [unknown/dynamic] structures, you can use custom JSON scalar type.

Related

Dynamic query string params in Wordpress Rest API

I cant find any information in the Wordpress rest api documentation about how to pass in a dynamic string as part of a url, I know how to do an ID.
register_rest_route($this->namespace, '/' . $this->rest_base . '/(?P<type>)', [
'args' => [
'type' => [
'description' => __('Type of notification to generate', $this->pluginName),
'type' => 'string',
'enum' => ['product_question']
]
],
[
'methods' => \WP_REST_Server::CREATABLE,
'callback' => [$this, 'create_item'],
'permission_callback' => [$this, 'create_item_permissions_check'],
'args' => $this->get_endpoint_args_for_item_schema(\WP_REST_Server::CREATABLE)
],
'schema' => [$this, 'get_public_item_schema']
]);
The above is the code im using to try and register the route. The route should look something like this /notifications/product_question The last part of the url, would be the dynamic part, and would be one of an array of values

How to add WooCommerce product content with html via rest api

I manage to generate simple Woocommerce product over REST api.
I fail to add product content with html code (e.g. table in my case).
The rest api
$api_response = wp_remote_post( $client_domain . '/wp-json/wc/v3/products', array(
'headers' => array(
'Authorization' => 'Basic ' . base64_encode( $K.':'.$S )
),
'body' => array(
'name' => $product_name, // product title
// 'status' => 'publish', // default: publish
'type' => 'simple',
'categories' => array(
array(
'id' => 22 // each category in a separate array
)
),
'regular_price' => $price, // product regular price
'price' => $price, // current product price
'description' => $allTable, // **** HTML TABLE ... *****
'short_description' => 'tilesim user product',
'visible' => true, // current product price 'images' => [ ['src' => $pimage] ] // array( "src" => $pimage)
'images' => [
[
'src' => $pimage
],
[
'src' => $rimage
]
]
)
The line with commented starts (****) has the variable ($allTable) that will be displayed as raw html instead of a table:
![beautified html]https://s-ivry.tilesim.co.il/wp-content/uploads/2019/01/woo_product_html.png)
How do I get over this issue and get the table, not the html markup?
PHP provides the htmlentities function which are used to encode and decode. Kindly check below examples how you can decode the php strings.
$str = '<a href="https://www.w3schools.com">w3schools.com</a>';
echo html_entity_decode($str);

How do I create a content type from SQL query?

<?php
function customtable_permission() {
return array(
'show people' => array(
'title' => t('List of people'),
'description' => t('The table'),
),
);
}
function customtable_menu() {
$items = array();
$items['people'] = array(
'type' => MENU_NORMAL_ITEM,
'title' => t('Title'),
'description' => 'This page should show a table from a remote DB',
'page callback' => 'customtable_db_data',
'access arguments' => array('show people'),
);
return $items;
}
function customtable_db_data() {
db_set_active('remote_database');
$results = db_query("SELECT * FROM {people}");
$header = array(t('Id'), t('Name'), t('Department'), t('Division'), t('Insurance'));
$rows = array();
foreach($results AS $result) {
$rows[] = array(
$result->id,
$result->name,
$result->department,
$result->division,
$result->insurance,
);
}
db_set_active('default');
return theme('table', array('header'=> $header, 'rows' => $rows));
}
?>
This all works fine and I can go to site.com/people and see the all the entries from the database printed nicely in a table
But I want text boxes where I can filter each column. Users can search by name or a specific insurance or department. I think it is possible programmatically, but I'd like to know if there is a more "drupal" approach. Content types have the ability to filter its fields. Am I to create a content type based on my query? I don't exactly know. Any assist is appreciated.
I think the best way to do this is migrate the query result to a drupal content type, to do this you need to use the migrate api.
-Install and enabled migrate and migrate_ui drupal modules.
-Create any content type you want with your fields.Using the drupal interface.
-Create a custom module, using migrate api. For example:
/sites/all/modules/custom/migrate_customtable/migrate_customtable.migrate.inc
function migrate_customtable_migrate_api() {
$api = array(
'api' => 2,
'groups' => array(
'custom_table' => array(
'title' => t('Custom Table'),
),
),
'migrations' => array(
'Projects' => array(
'class_name' => 'CustomTableMigration',
'group_name' => 'custom_table',
'event_log' => ''
),
),
);
return $api;
}
Then, create a class called: CustomTableMigration.inc that will contains the migration:
<?php
/**
* Created by PhpStorm.
* User: ldcontreras
* Date: 25/07/18
* Time: 10:13
*/
class CustomTableMigration extends Migration {
public function __construct($arguments) {
parent::__construct($arguments);
$query = Database::getConnection('default', 'migrate_custom_table')//this must be define in your settins.php file
->select('people')
->fields('productos_new', array(
'id',
'name',
'department',
'division',
'insurance',
)
);
$this->source = new MigrateSourceSQL($query, array(), NULL, array(map_joinable => FALSE));
$this->destination = new MigrateDestinationNode('content_type_machine_name'); //the content type created
$this->map = new MigrateSQLMap($this->machineName,
array(
'id' => array(
'type' => 'int',
'unsigned' => TRUE,
'not null' => TRUE,
'description' => t('Source ID'),
)
),
MigrateDestinationNode::getKeySchema()
);
$this->addFieldMapping('title', 'name');
$this->addFieldMapping('field_department_content_type', 'department');
$this->addFieldMapping('field_division_content_type', 'division');
$this->addFieldMapping('field_insurance_content_type', 'insurance');
$this->addUnmigratedDestinations(array(
'body:format',
'comment',
'is_new',
'log',
'promote',
'revision',
'revision_uid',
'tnid',
'totalcount',
'daycount',
'timestamp',
'path',
'translate',
'sticky',
'uid',
));
}
}
Finally,enable your custom module and run the migration using drush.

Woocommerce REST API how send custom meta?

Woocommerce not send meta with custom plug-ins in format .json.
What should I add to the file functions.php?
How to forcibly compel him to send some meta?
Sorry for such a simple question, but I have not found a solution for spaces google
Send the following payload to the API:
$data = [
'name' => 'Product Name',
'type' => 'simple',
'regular_price' => '19.95',
'description' => 'Simple Product,
'categories' => [
['id' => 1]
],
'virtual' => true,
'reviews_allowed' => false,
'meta_data' => [
[
'key' => '_custom_meta_1',
'value' => 'value1'
],
[
'key' => '_custom_meta_2',
'value' => 'value2'
]
]
];
the "meta_data" field, should be an array, containing arrays with "key" and "value" attributes.

Correct way to use Drupal 7 Entities and Field API

I'm trying to use Drupal 7's entities and field API to correctly build a new module. What I have been unable to understand from the documentation is the correct way to use the new API to create a 'content type' (not a node type) with a number of set fields, such as Body.
I'm trying to set up the entity using hook_entity_info, then I believe I need to add the body field using field_create_instance, but I can't seem to get it to work.
In mycontenttype.module:
/**
* Implements hook_entity_info().
*/
function mycontenttype_entity_info() {
$return = array(
'mycontenttype' => array(
'label' => t('My Content Type'),
'controller class' => 'MyContentTypeEntityController',
'base table' => 'content_type',
'uri callback' => 'content_type_uri',
'entity keys' => array(
'id' => 'cid',
'label' => 'title',
),
'bundles' => array(
'mycontenttype' => array(
'label' => 'My Content Type',
'admin' => array(
'path' => 'admin/contenttype',
'access arguments' => array('administer contenttype'),
),
),
),
'fieldable' => true,
),
);
return $return;
}
/**
* Implements hook_field_extra_fields().
*/
function mycontenttype_field_extra_fields() {
$return['mycontenttype']['mycontenttype'] = array(
'form' => array(
'body' => array(
'label' => 'Body',
'description' => t('Body content'),
'weight' => 0,
),
),
);
return $return;
}
Then does this go in the .install file?
function mycontenttype_install() {
$field = array(
'field_name' => 'body',
'type' => 'text_with_summary',
'entity_types' => array('survey'),
'translatable' => TRUE,
);
field_create_field($field);
$instance = array(
'entity_type' => 'mycontenttype',
'field_name' => 'body',
'bundle' => 'mycontenttype',
'label' => 'Body',
'widget_type' => 'text_textarea_with_summary',
'settings' => array('display_summary' => TRUE),
'display' => array(
'default' => array(
'label' => 'hidden',
'type' => 'text_default',
),
'teaser' => array(
'label' => 'hidden',
'type' => 'text_summary_or_trimmed',
),
),
);
field_create_instance($instance);
}
I think your problem is that if node module is installed, there is already a field named 'body'. You should either re-name your field to something like 'mycontenttype_body' (comment.module uses comment_body), or re-use the 'body' field and skip the adding the field part and skip to adding the instance of it. The former is recommended over the latter.
Every field has an array property, entity_types, which limits the entities to which the field can be attached.
The best Drupal solution I can find, hook_field_create_field, can alter fields as they are created, but that's no good for the body field which is created on installation.
So my solution is just to edit the database directly in my hook_install
$data_col = db_query("SELECT data from field_config where field_name = 'body'")->fetchAssoc();
$data = unserialize($data_col['data']);
$data['entity_types'][] = 'MY_ENTITY_TYPE';
db_update('field_config')
->fields(array('data' => array('data' => serialize($data))))
->condition('field_name', 'body')
->execute();
just started down the same path here is a video from fago
Here's a nice repo to start: Lawmakers entity

Resources