Viewing 8 posts - 1 through 8 (of 8 total)
  • Author
    Posts
  • #57782
    chrisdavies71
    Participant

    Hi Zac,

    Hope you are well.

    I have a block set up and am storing some data in the postmeta database table (an APIKey).

    I need to use get_post_meta in a class.php file so that i can then access the meta data. Something like this:
    $this->apikey = get_post_meta( '869', 'current_rms_apikey', 'true' );

    Currently the post_id is hard coded “869” but I need this to be dynamic as it is in a plugin and i will not always know where the block has been placed.

    Any advice? I tried get_the_ID() but that gives me an error.

    Regards

    CHRIS

    #57795
    Zac Gordon
    Keymaster

    Is this in a dynamic PHP block? Mind posting all of the PHP code for this so I can see the whole thing? You should have access to the $post to grab the ID but I might be misunderstanding.

    #57803
    chrisdavies71
    Participant

    Hi Zac,

    Here is the class.php file which is where i need to do the post ID stuff. If you need anything else let me know.

    <?php
    
    include_once("../../../../../wp-load.php");
    
    if ( ! defined( 'ABSPATH' ) ) {
    	exit;
    }
    
    class current_rms_api
    {
        //TODO: Make the version selectable from a dropdown in InspectorControls - currently only v1.
        //NOTE: apikey ad subdomain are here for reference only remove later
        //private $apikey = 'JNxCt3e_mNa-M2v71qJF';
        //private $subdomain = 'cpackham';
        private $version = 'v1';
    
        //public function __construct( $postid) {
        public function __construct() {
            //$settings = get_option( 'cp_currentrms_settings' );
            //print_r ($settings);
            //$this->apikey = $settings['cp_currentrms_apikey'];
            //$this->subdomain = $settings['cp_currentrms_subdomain'];
            //$this->apikey = get_post_meta( $postid, 'current_rms_apikey', 'true' );
            //$this->subdomain = get_post_meta( $postid, 'current_rms_subdomain', 'true' );
            $this->apikey = get_post_meta( '869', 'current_rms_apikey', 'true' );
            $this->subdomain = get_post_meta( '869', 'current_rms_subdomain', 'true' );
        }
    
        private function query( $endpoint, $params=array())
        {
            $params['subdomain']=$this->subdomain;
            $params['apikey']=$this->apikey;
            // Call API url
            $url = 'https://api.current-rms.com/api/'.$this->version.'/'.$endpoint.'?' . http_build_query($params);
    
            //echo $url;
    
            $ch = curl_init($url);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            $response = curl_exec($ch);
            curl_close($ch);
    
            $data = json_decode($response);
    
            return $data;
        }
    
        // Function gets a list of product groups (categories).
        public function getProductGroups()
        {
            $data = $this->query('product_groups');
            return $data->product_groups;
        }
    
        // Function gets a list of products in a product group (category).
        // NOTE: You can not do this using the id of the product group.
        // TODO: See if we can get this to only show categories that have a product count / hide empty categories
        // TODO: See if we can get this to show only product with a specific tag (so that tab panel nav works.
        public function getProducts( $name )
        {
            $data = $this->query('products', array('q[product_group_name_eq]'=>$name,'q[accessory_only_eq]'=>false,'per_page'=>100));
            return $data->products;
        }
    
        // Function gets an individual product based on the product ID.
        public function getProduct( $id )
        {
            $data = $this->query('products/' . $id);
            return $data->product;
        }
    
        // Function gets a list of accessories based on the product ID
        public function getAccessories( $id )
        {
            $data = $this->query('products/' . $id . '/accessories');
            return $data->accessories;
        }
    
        // Function gets the price based on the product ID
        public function getProductPrice( $id )
        {
            $data = $this->query('products/' . $id . '/item_price');
            return $data->data;
        }
    
        // Function gets the rate definitions for the products
        public function getRates( $id )
        {
            $data = $this->query('rate_definitions/' . $id );
            return $data->rate_definition;
        }
    
        // Function gets a list of tags
        public function getTags()
        {
            $data = $this->query('products/tag_cloud');
            return $data->tag_cloud;
        }
    
        // Function gets products by tag
        public function getProductsbyTag( $tag )
        {
            $data = $this->query('products', array('tags'=>'['.$tag.']'));
            return $data->products;
        }
    
    }
    ?>

    Regards

    CHRIS

    #57811
    Zac Gordon
    Keymaster

    Okay, I guess I need to see the code where you are using this with your Gutenberg block.

    Is this for a dynamic block? Could I see how you’re integrating this with the PHP for the dynamic block? Within that you should have access to the global $post if you need.

    Thanks!

    #57829
    chrisdavies71
    Participant

    Hi Zac,

    Here is the block.js file:

    /**
     * BLOCK: current-rms-for-wordpress-gutenberg
     *
     * Registering a basic block with Gutenberg.
     * Simple block, renders and saves the same content without any interactivity.
     */
    
    //  Import CSS.
    import './style.scss';
    import './editor.scss';
    import icon from './icon';
    import logo from './current-rms-logo.png';
    
    const { __ } = wp.i18n; // Import __() from wp.i18n
    const { registerBlockType } = wp.blocks; // Import registerBlockType() from wp.blocks
    const { InspectorControls, } = wp.editor;
    const { PanelBody, PanelRow, TextControl} = wp.components;
    
    /**
     * Register: aa Gutenberg Block.
     *
     * Registers a new block provided a unique name and an object defining its
     * behavior. Once registered, the block is made editor as an option to any
     * editor interface where blocks are implemented.
     *
     * @link https://wordpress.org/gutenberg/handbook/block-api/
     * @param  {string}   name     Block name.
     * @param  {Object}   settings Block settings.
     * @return {?WPBlock}          The block, if it has been successfully
     *                             registered; otherwise <code>undefined</code>.
     */
    registerBlockType( 'cgb/current-rms-for-wordpress-gutenberg', {
    	// Block name. Block names must be string that contains a namespace prefix. Example: my-plugin/my-custom-block.
    	title: __( 'Current RMS' ), // Block title.
    	description: 'Show your Current RMS system on your WordPress website using the new Gutenberg editor',
    	icon: icon.current_rms_icon, // Block icon.
    	category: 'embed', // Block category — Group blocks together based on common traits E.g. common, formatting, layout widgets, embed.
    	keywords: [
    		__( 'Hire' ),
    		__( 'Sales' ),
    		__( 'Store' ),
    	],
    	attributes: {
    		apikey: {
    			type: 'string',
    			source: 'meta',
    			meta: 'current_rms_apikey'
    		},
    		subdomain: {
    			type: 'string',
    			source: 'meta',
    			meta: 'current_rms_subdomain'
    		},
    	},
    
    	/**
    	 * The edit function describes the structure of your block in the context of the editor.
    	 * This represents what the editor will render when the block is used.
    	 *
    	 * The "edit" property must be a valid function.
    	 *
    	 * @link https://wordpress.org/gutenberg/handbook/block-api/block-edit-save/
    	 */
    	 edit: function( props ) {
    		 console.log ('output of props in edit:');
    		 console.log ( props );
    		const { attributes, setAttributes } = props;
    		const { apikey, subdomain } = props.attributes;
    		const onChangeAPIKey = value => { props.setAttributes( { apikey: value } ) };
    		const onChangeSubDomain = value => { props.setAttributes( { subdomain: value } ) };
    
     		return ([
    			<InspectorControls>
    			  <PanelBody title={ __( 'API Settings' ) } >
    				  <PanelRow>
    						<TextControl
    						  label={ __( 'API Key' ) }
    							value={ apikey }
    							onChange={ onChangeAPIKey }
    						/>
    					</PanelRow>
    					<PanelRow>
    					  <TextControl
    						  label={ __( 'Subdomain' ) }
    							value={ subdomain }
    							onChange={ onChangeSubDomain }
    						/>
    					</PanelRow>
    				</PanelBody>
    			</InspectorControls>,
    			// Creates a <p class='wp-block-cgb-block-cp-current-rms-plugin'></p>.
     		  <div className={ props.className }>
     				<img className="currentlogo" src="../wp-content/plugins/current-rms-for-wordpress-gutenberg/dist/assets/current-rms-logo.png" />
    				{/*<img src={logo} className="currentlogo" alt="current-logo" />.*/}
     			</div>
     		]);
     	},
    
    	/**
    	 * The save function defines the way in which the different attributes should be combined
    	 * into the final markup, which is then serialized by Gutenberg into post_content.
    	 *
    	 * The "save" property must be specified and must be a valid function.
    	 *
    	 * @link https://wordpress.org/gutenberg/handbook/block-api/block-edit-save/
    	 */
    	 save: function( props ) {
    		 console.log ('output of props in save:');
    		 console.log ( props );
     		return (
     			<div>
     				<div id="productlist">Loading...</div>
     					<script src="../wp-content/plugins/current-rms-for-wordpress-gutenberg/dist/assets/ajax.js"></script>
     			</div>
     		);
     	},
     } );
    #57831
    chrisdavies71
    Participant

    Here is the ajax.php file:

    <?php
    
    require_once ( './class.php' );
    
    define ('AJAX_URL', $_SERVER['PHP_SELF']);
    
    function render_breadcrumb( $links=array() )
    {
        $html = '<div class="row mb-3">';
        $html .= '<div class="col-md-11">';
        $html .= '<nav aria-label="breadcrumb">';
        $html .= '<ol class="breadcrumb">';
        $html .= '<li class="breadcrumb-item"><a href="/">Home</a></li>';
        $html .= '<li class="breadcrumb-item"><a href="#" onclick="ajax_load(\'query=product_groups\')">Hire&nbsp;&&nbsp;Sales</a></li>';
        foreach ($links as $query=>$name)
        {
            $html .= '<li class="breadcrumb-item"><a href="#" onclick="ajax_load(\''.$query.'\')">'.$name.'</a></li>';
        }
        //$html .= '<li class="breadcrumb-item active" aria-current="page">Data</li>';
        $html .= '</ol>';
        $html .= '</nav>';
        $html .= '</div>';
        $html .= '<div class="col-md-1">';
        $html .= '<button type="button" class="btn btn-primary" onclick="window.history.go(-1);">Back</button>';
        $html .= '</div>';
        $html .= '</div>';
    
        return $html;
    }
    
    switch( $_GET['query'] )
    {
        // Product Groups (Categories) Page
        case 'product_groups':
            //$objCurrentRmsApi = new current_rms_api( $_GET['postid']);
            $objCurrentRmsApi = new current_rms_api();
            $product_groups = $objCurrentRmsApi->getProductGroups();
    
            $html = render_breadcrumb();
    
            $html .= '<div class="row">';
            foreach( $product_groups as $product_group )
            {
    
                $html .= '<div id="productlist" class="col-md-4">';
                $html .= '<div class="card">';
                if (isset ($product_group->icon->url) ) {
                    $html .= '<img class="card-img-top" style="padding:1.25rem" src="'. $product_group->icon->url . '">';
                }
                $html .= '<div class="card-body">';
                $html .= '<h5 class="card-title">' . $product_group->name . '</h5>';
                $html .= '<p class="card-text">' . $product_group->description . '</p>';
                $html .= '<a href="#" style="cursor:pointer" onclick="ajax_load(\'query=products&name=' . urlencode($product_group->name) . '\');" class="btn btn-primary">View Products</a>';
                $html .= '</div>';
                $html .= '</div>';
                $html .= '</div>';
    
            }
            $html .= '</div>';
            echo $html;
    
        break;
    
        // Products in each Product Group (Category)
        case 'products':
            $objCurrentRmsApi = new current_rms_api();
            $products = $objCurrentRmsApi->getProducts( $_GET['name'] );
            //$tags = $objCurrentRmsApi->getTags();
            $tags=array();
            foreach ($products as $product)
            {
                foreach ($product->tag_list as $tag)
                {
                    if (!in_array($tag, $tags)) {
                        $tags[]=$tag;
                    }
                }
    
            }
            sort($tags);
    
            $html = render_breadcrumb(array('query=products&name='.urlencode($_GET['name'])=>$_GET['name']));
    
            $counter = 0;
    
            $html .= '<ul class="nav nav-tabs flex-column flex-sm-row nav-fill" id="myTab" role="tablist">';
            foreach ($tags as $tag)
            {
                $html .= '<li class="flex-sm-fill text-center nav-item">';
                $html .= '<a class="nav-link' . ($counter == 0 ? ' active' : '') . '" id="' . preg_replace('/\s+/', '_', $tag) . '_tab" data-toggle="tab" href="#' . preg_replace('/\s+/', '_', $tag) . '" role="tab" aria-controls"' . preg_replace('/\s+/', '_', $tag) . '" aria-selected="' . ($counter == 0 ? 'true' : 'false') .'">' . $tag . '</a>';
                $html .= '</li>';
                $counter++;
            }
            $html .= '</ul>';
    
            $html .= '<div class="tab-content mt-4" id="myTabContent">';
            $counter2 = 0;
            foreach ($tags as $tag)
            {
                $html .= '<div class="tab-pane fade' . ($counter2 == 0 ? ' show active' : '') . '" id="' . preg_replace('/\s+/', '_', $tag) . '" role="tabpanel" aria-labelledby="' . preg_replace('/\s+/', '_', $tag) . '_tab">';
                $html .= '<div class="row">';
                foreach( $products as $product )
                {
                    if (in_array($tag, $product->tag_list))
                    {
                        $html .= '<div class="col-md-4">';
                        $html .= '<div class="card">';
                        if (isset ($product->icon->url) )
                            {
                                $html .= '<img class="card-img-top p-3" src="'. $product->icon->url . '">';
                            } //end product icon isset
                        $html .= '<div class="card-body">';
                        $html .= '<h5 class="card-title">' . $product->name . '</h5>';
                        $html .= '<a href="#" style="cursor:pointer" onclick="ajax_load(\'query=product&id=' . urlencode($product->id) . '\');" class="btn btn-primary">View Product</a>';
                        //$html .= $product_tag;
                        $html .= '</div>'; //end card-body
                        $html .= '</div>'; //end card
                        $html .= '</div>'; //end col
                    } //end product_tag foreach
                }// end product foreach
                $html .= '</div>'; //end row
                $html .= '</div>'; //end tab-pane
                $counter2++;
            }// end tags foreach
    
            $html .= '</div>'; //end tab-content
            echo $html;
    
        break;
    
        // Individual Product Page
        case 'product':
            $objCurrentRmsApi = new current_rms_api();
            $product = $objCurrentRmsApi->getProduct( $_GET['id'] );
            $accessories = $objCurrentRmsApi->getAccessories( $_GET['id'] );
            $price = $objCurrentRmsApi->getProductPrice( $_GET['id'] );
            $rates = $objCurrentRmsApi->getRates( $price->rate_definition_id );
    
            $labels = array('1_day'=>'Daily', 'weekend'=>'Weekend', 'week'=>'Weekly', 'subs_day'=>'Additional Days');
    
            $html = render_breadcrumb(array('query=products&name='.urlencode($product->product_group->name)=>$product->product_group->name,'query=product&id='.$_GET['id']=>$product->name));
    
            $html .= '<div class="row">';
            $html .= '<div class="col-md-6 item-photo">';
            if (isset ($product->icon->url) ) {
                $html .= '<img style="max-width:100%;" src="' . $product->icon->url . '" />';
            }
            $html .= '</div>';
            $html .= '<div class="col-md-6" style="border:0px solid gray">';
            $html .= '<h1>' . $product->name . '</h1>';
            $html .= '<p>' . $product->description . '</p>';
            $html .= 'Supplied with the following accessories:';
            $html .= '<ul class="list-group list-group-flush mb-3">';
            foreach( $accessories as $accessory )
            {
                $html .= '<li class="list-group-item border-0">' . $accessory->related_name . '</li>';
            }
            $html .= '</ul>';
            $html .= '<table class="table">';
            $html .= '<thead class="thead-light">';
            $html .= '<tr>';
            $html .= '<th scope="col">Hire Period</th>';
            $html .= '<th scope="col">Cost</th>';
            $html .= '</tr>';
            $html .= '</thead>';
            $html .= '<tbody>';
            foreach ( $rates->rate_engine->rate_engine->config->charging_periods as $code=>$rate) {
                $html .= '<tr><th>' . $labels[$code] . '</th><td>&pound;' . number_format($price->price * $rate->default_value / 100,2)  .'</td></tr>';
            }
            $html .= '</tbody>';
            $html .= '</table>';
            //$html .= '<!-- Hire and Sale Buttons -->';
            //$html .= '<div class="section" style="padding-bottom:20px;">';
            //$html .= '<button class="btn btn-success">Agregar al carro</button>';
            //$html .= '<button class="btn btn-success">Agregar al carro</button>';
            //$html .= '</div>';
            $html .= '</div>';
            echo $html;
    
        break;
    
        default:
            echo 'Invalid query';
    }
    ?>
    #57838
    chrisdavies71
    Participant

    And finally the ajax.js file:

    function ajax_load( query )
    {
      jQuery('#productlist').load('../wp-content/plugins/current-rms-for-wordpress-gutenberg/dist/assets/ajax.php?postid=&'+query);
    }
    ajax_load('query=product_groups');
    #57925
    Zac Gordon
    Keymaster

    Okay, having a little trouble following all of this, but hope I can help.

    The first thing I’ll say that won’t be super helpful, but this model of AJAX is not really how Gutenberg wants you to be developing anymore. It would rather you build custom API endpoints that can handle these requests. That said we can probably hack this together.

    In the JS for your block you will need to use the Editor Data Redux store to get the post ID https://wordpress.org/gutenberg/handbook/data/data-core-editor/#getcurrentpostid

    You should be able to then pass that into your AJAX call.

    Hope this helps, let me know how it goes..

Viewing 8 posts - 1 through 8 (of 8 total)
  • You must be logged in to reply to this topic.