mpratt / Embera

A Oembed consumer library, that gives you information about urls. It helps you replace urls to youtube or vimeo for example, with their html embed code. It has advanced features like offline support, responsive embeds and caching support.
MIT License
339 stars 59 forks source link

Specify provider(s) #23

Closed ayndev closed 9 years ago

ayndev commented 9 years ago

Thanks for this awesome library, The issue is, what if i want to specify specifec provider(s) for my request, so it will return if this url is from this provider or not before getting the data and then checking the provider name and stuff ? is this possible ?, or I need to do the filter for the url before using the embera class?

Thanks

mpratt commented 9 years ago

Hi ayndev,

If I understand your Issue correctly, what you want to do is to allow only certain providers. Right now there is no simple way to achieve this. I'm going to work on that, the next major version of this library (don't ask me when).

However you do have an alternative. What you need to do first is extend the Providers class and add the providers you want to use. Lets say for example you just want to allow Youtube and Vine.

class MyCustomProviders extends \Embera\Providers
{
    /** @var array An array with the providers you want to allow. */
    protected $services = array(
        'm.youtube.com' => '\Embera\Providers\Youtube',
        'youtube.com' => '\Embera\Providers\Youtube',
        'youtu.be' => '\Embera\Providers\Youtube',
        'vine.co' => '\Embera\Providers\Vine',
    );
}

Now that you have a providers class, we need to extend the main Embera class so that we can use our custom provider class

class MyCustomEmbera extends \Embera\Embera
{
    /** inline {@inheritdoc} */
    public function __construct(array $config = array())
    {
        parent::__construct($config);
        $this->providers = new MyCustomProviders($this->config, $this->oembed);
    }
}

Now you just need to use your MyCustomEmbera class for all your oembed stuff.

$text = 'Check this video out http://vimeo.com/groups/shortfilms/videos/66185763 and https://www.youtube.com/watch?v=NFdbvWjfbpA&feature=youtu.be ';

$myEmbera = new MyCustomEmbera();
echo $myEmbera->autoEmbed($text);

As you can see, the vimeo link will not be parsed, however the youtube should work.

Please tell me if this works for you or if I misunderstood your issue!

ayndev commented 9 years ago

First thank you for your quick reply. No, you did understood my issue exactly, don't you think it's important ? so in the config you can specify certain providers or defaut is all. for example

$object = new Embera([
    'providers' => [ 'youtube' , 'vimeo' , ..... ] , 
[);

The issue for me is that i want to do something flexible, because i'm designing to use this awesome library in different input forms of my platform, and for this I need to specify/restrict some providers for every form. (ex. in some places only from circuits lab or amCharts)

So i'm not sure that i will go directly with this solution, rather i may extend a flexible class that take some parameters based on the situation. but for the services where i can find all the hosts for certain provider as in you example

    protected $services = array(
        'm.youtube.com' => '\Embera\Providers\Youtube',
        'youtube.com' => '\Embera\Providers\Youtube',
        'youtu.be' => '\Embera\Providers\Youtube',
        'vine.co' => '\Embera\Providers\Vine',
    );

so i can for example pass only 'Youtube' and it load these ? Again thank you very much for your support, I hope i did't bother you

mpratt commented 9 years ago

No problem ayndev! Thanks for your suggestion. This is something I thought about before but I saddly I've been busy and got very little time to work on the new version of this library. The next version of this library will be more friendly on this aspect, but as I said earlier, I don't know when it is going to be ready.

You can find the relationship between providers and classes in the Providers Class.

If I were you, I would create an Embera and Providers Adapter.

class ProvidersAdapter extends \Embera\Providers
{
    /** Removes providers from the services property, that are not inside the $providers array */
    public function filterProviders(array $providers)
    {
         $providersRegex = str_replace('\|', '|', preg_quote(implode('|', $providers), '~'));
         $this->services = array_filter($this->services, function ($service) use ($providersRegex) {             
             return preg_match('~' . $providersRegex . '~i', $service);
         });
     }
}

class EmberaAdapter extends \Embera\Embera
{
    /** inline {@inheritdoc} */
    public function __construct(array $config = array())
    {
        parent::__construct($config);
        if (!empty($config['providers'])) {
            $this->providers = new ProvidersAdapter($this->config, $this->oembed);
            $this->providers->filterProviders($config['providers']);
        }        
    }
}

Now that you have this, you can have a form with the name of the providers and create an array. You only need to pass it to your EmberaAdapter as a configuration key.


/** 
 * As an example I'm writing the name of the providers, 
 * but You can fetch the values directly from $_POST
 * after some minor cleanup.
 */
$myproviders = array('Youtube', 'Vine', 'Instagram');

$emberaAdapter = new EmberaAdapter(array(
    'providers' => $myproviders
));

$text = 'http://vimeo.com/groups/shortfilms/videos/66185763 and https://www.youtube.com/watch?v=NFdbvWjfbpA&feature=youtu.be and https://vine.co/v/e5DZzdLLXeK and https://instagram.com/p/2a4OYWumA_/?taken-by=tupuntosex';

echo $emberaAdapter->autoEmbed($text);

By doing this you have a couple of advantages:

Check the code! It's late , I haven't tested it, but I think it should work. I'm sure It can be optimized (the regex part looks a little ugly).

As I said, I'm planning on enhancing this part of the library on the next major version (~2.0), but It is going to take me some time.

Thanks for the report!

ayndev commented 9 years ago

Thank you very much. It seems that you already wrote the code for me :) I would'nt want to take your time. any way thanks, it seems that you enjoy this.

I know this feeling that your are very buzy, and there still many work you want to do. Take you time and don't feel upset, maybe during this time, new ideas come and you write v 2.0 in a better prospective. It's called (continuous improvement). It does't end. You already did a great job. I searched for many oembed libraries, I found some, but they didn't support (circuitsLab & ... ) some "educational" providers as I need, then I sticked to yours. I'm yii2 developer Finally I'm happy contributing in your project, Thanks again. I think i will close this issue now Salam