ansonphong / postworld

Wordpress Theme Development Framework
GNU General Public License v2.0
7 stars 0 forks source link

oEmbed AJAX Issues #59

Closed ansonphong closed 10 years ago

ansonphong commented 10 years ago

Hi Michel, I'm having a very strange issue happening which I wanted to ask you about.

So I wrote and implemented the basic methods for Wordpress oEmbed using AJAX, to get the embed code for a given URL - and everything is working quite nicely, I'm getting the expected response via AJAX, and everything is good - except there's one problem.

When I try and print it, it comes in the form of some kind of serialized object, with the embed code as the value of all these keys.

{"0":"\n","1":"\n","2":"\n","3":"\n","4":"\n","5":"\n","6":"\n","7":"\n","8":"<","9":"i","10":"f","11":"r","12":"a","13":"m","14":"e","15":" ","16":"w","17":"i","18":"d","19":"t","20":"h","21":"=","22":"\"","23":"5","24":"0","25":"0","26":"\"","27":" ","28":"h","29":"e","30":"i","31":"g","32":"h","33":"t","34":"=","35":"\"","36":"2","37":"8","38":"1","39":"\"","40":" ","41":"s","42":"r","43":"c","44":"=","45":"\"","46":"h","47":"t","48":"t","49":"p","50":":","51":"/","52":"/","53":"w","54":"w","55":"w","56":".","57":"y","58":"o","59":"u","60":"t","61":"u","62":"b","63":"e","64":".","65":"c","66":"o","67":"m","68":"/","69":"e","70":"m","71":"b","72":"e","73":"d","74":"/","75":"3","76":"8","77":"p","78":"e","79":"W","80":"m","81":"7","82":"6","83":"l","84":"-","85":"U","86":"?","87":"f","88":"e","89":"a","90":"t","91":"u","92":"r","93":"e","94":"=","95":"o","96":"e","97":"m","98":"b","99":"e","100":"d","101":"\"","102":" ","103":"f","104":"r","105":"a","106":"m","107":"e","108":"b","109":"o","110":"r","111":"d","112":"e","113":"r","114":"=","115":"\"","116":"0","117":"\"","118":" ","119":"a","120":"l","121":"l","122":"o","123":"w","124":"f","125":"u","126":"l","127":"l","128":"s","129":"c","130":"r","131":"e","132":"e","133":"n","134":">","135":"<","136":"/","137":"i","138":"f","139":"r","140":"a","141":"m","142":"e","143":">"}

What do I need to do in this case to make it work?

Here is the function so you can look :

js/app.js

I added controller function mediaEmbed

js/services/pwData.js

I added ajax_oembed_get to the service.

php/postworld_ajax.php

I added ajax_oembed_get()

Test Button

You can test it anywhere with this HTML, by clicking the button to see what I'm talking about:

<div class="o_embed" ng-controller="mediaEmbed">
<div>{{oEmbed}}</div>
<div ng-bind-html="oEmbedDecode"></div>
<button ng-click="oEmbedGet('http://www.youtube.com/watch?v=38peWm76l-U')">Get o Embed</button>
</div>

Thanks!!

ansonphong commented 10 years ago

Once I've got this figured out, I'll be able to implement most of Haidy's PHP functions through the pwData service.

ansonphong commented 10 years ago

UPDATE : By using .then following the ajax call, and then doing a manual foreach decode, I can get the string, and using $sce service, make it 'trustable' HTML, but the manual decode step seems like a hack - not best practices.

Do you know a better way to get the AJAX response without manually decoding it?

Here's the new test button which is working with the "hack"

Test Button

<div class="o_embed" ng-controller="mediaEmbed">
<div>{{oEmbed}}</div>
<div ng-bind-html="oEmbedDecode"></div>
<button ng-click="oEmbedGet('http://www.youtube.com/watch?v=38peWm76l-U')">Get o Embed</button>
</div>
michelhabib commented 10 years ago

Fixed:) Please get the latest [plugin and theme] and go to http://localhost/wordpress/search/#/o-embed/

First thing, ajax returns need to be returned as ajax, i already put a framework to do that and using it in the postworld_ajax file, so the function would look like this:

function ajax_oembed_get(){
    list($response, $args, $nonce) = initAjaxResponse();
    $pw_args = $args;
    $oEmbed = wp_oembed_get( $pw_args['link_url'] );
    header('Content-Type: application/json');
    $response['status'] = 200;
    $response['data'] = $oEmbed;
    echo json_encode($response);
    // die ( $oEmbed );
    die;
}

The json header line and the json encode line do most of the magic. This way, the return will be a regular string inside the api wrapper to help with error and status tracking.

second thing, and you already got this tough one right, is the html binding. When binding html with ngSanitize, you protect your users against malicious scripts, but since you are trusting the embed function, the right way to go is to use the $sce.trustAsHtml function. using the then function is a must, since it returns only when the response is ready. we are using the $q library all over the app to manage asynchronous calls.

        pwData.wp_ajax('ajax_oembed_get', args ).then(
            // Success
            function(response) {    
                $scope.oEmbed = $sce.trustAsHtml(response.data); // we are returning the response in a json object that has status, error, data objects, so we are using response.data to retrieve the embed data.
            },
            // Failure
            function(response) {
                alert("error");
            }
        );
ansonphong commented 10 years ago

Great, thanks! I'll have a look at this. This will help me develop various other AJAX functions.