Best approach To include 3rd party files with Symfony2 - symfony

I would like to know What is the best way to include 3rd party php files in symfony2. I am using a different php - ajax package for uploading files in my symfony2 application. The package offers me some php oops code which i need to use in my symfony controller. I am creating objects of that code in my controller. So i would like to know where i can put that third party code or file and how can i include or create objects of that code in my symfony2 controller. Do we use require or include in symfony2 as well. If So is that the only approach.

I'm not so sure about trying to add namespaces to a third party library. Twig, for example, does not use name spaces. And there really is no need. Consider for example a case where you want to use the PDF component from the Zend_Framework 1 library.
In your app/autoload.php file you would do something like:
$loader->registerPrefixes(array(
'Twig_Extensions_' => $ws . 'Symfony/vendor/twig-extensions/lib',
'Twig_' => $ws . 'Symfony/vendor/twig/lib',
'Zend_' => $ws . 'ZendFramework-1.0.0/library',
));
// And since Zend internally uses require/include we need to set an include path
ini_set('include_path','.' .
PATH_SEPARATOR . $ws . 'ZendFramework-1.0.0/library'
);
At this point we should be able to create 3rd part objects inside of controllers while letting the autoload system take care of finding and including the classes:
$page = new \Zend_Pdf_Page(\Zend_Pdf_Page::SIZE_A4);
$doc->pages[] = $page;
$font1 = \Zend_Pdf_Font::fontWithName(\Zend_Pdf_Font::FONT_HELVETICA);
$font2 = \Zend_Pdf_Font::fontWithName(\Zend_Pdf_Font::FONT_COURIER_BOLD);
You do have to use the \ to get around the lack of namespacing.
This answer does assume that your 3rd part library follows the more or less standard class naming convention. If it has it's own auto loading functionality then just call it from autolaod.php as well. And if you don't want to use autoloading at all then just set the include path and include away.

The documentation explains the directory structure in detail.
Basically, you can put them wherever you want, but for the sake of consistency and following best-practices, you should put your third-party libraries in vendor/ directory.
Than you can include the relevant files with namespaces.

Related

Symfony4 how to call a file in public folder?

I need to display a yaml file as an array but i but I can't display it.
I have create a service, and my controller call this service.
In my service i try to call my yaml like this :
$value = Yaml::parseFile('public\assets\organizations.yaml');
return $value;
But that return me that error :
File "public\assets\organizations.yaml" does not exist.
You are specifying the file with a relative path. This will not be resolved relative to the file it is in but relative to the current working directory you are in when executing the script. Since this depends on various factors it will always be troublesome.
Thus you should always use absolute paths. In symfony you can get the base path of your project via the kernel.project_dir configuration parameter.
Your code does not provide enough context to understand how or where you are using it. But if it is inside a controller extending AbstractController you can use getParameter():
$projectDir = $this->getParameter('kernel.project_dir');
$absolutePath = $projectDir . '/public/assets/organizations.yml';
$value = Yaml::parseFile($absolutePath);
return $value;
Also note that using \ as the directory separator won't work under Linux/Unix-like systems where / is used as directory separator!
Since / will work as directory separator under Windows, too, it is easiest to use it for cross-OS compatibility. Alternatively use the DIRECTORY_SEPARATOR constant.

Wordpress: how to call method and output?

I am using a Wordpress plugin found here https://github.com/hirezstudios/smite-api-wp . Issue I have is the readme says I need to:
// call a method
global $smiteAPI;
$gods = $smiteAPI->getGods(1);
// do whatever with the god data...
I understand I need to implement it on one of my .php files or generate a new one. However, I am unsure what call a method means or how to make the above work. The getGods(1) will return a .json file of all gods in a game called Smite; 1 tells the API english.

reading yaml from twig

Preface: in ez4 i remember there was a tpl function to read ini settings, we used to use this to pass specific locations or id's with which we could then render certain content.
In ezplatform I am now doing the same thing but by using the PreContentViewListener (in the PreContentViewListener read a yml file and pass into the view as params), but this doesn't feel like the correct way as the PreContentViewListener doesn't always get triggered, in custom controllers for example.
Question
Is there a native way to read yaml files from within twig templates? After searching the docs and available packagists i cannot find anything :/
If your needs are simple (i.e. reading container parameters), you can also use eZ Publish config resolver component which is available in any Twig template with ezpublish.configResolver.
You can specify a siteaccess aware parameter in format <namespace>.<scope>.<param_name>, like this:
parameters:
app.default.param.name: 'Default param value'
app.eng.param.name: 'English param value'
app.cro.param.name: 'Croatian param value'
where default, eng and cro are different eZ Publish scopes.
You can then use the config resolver to fetch the parameter in current scope with:
{{ ezpublish.configResolver.parameter('param.name', 'app') }}
If you have Legacy Bridge installed, this even falls back to legacy INI settings if no Symfony container parameter exists:
{{ ezpublish.configResolver.parameter('SiteSettings.SiteName', 'site') }}
Disclaimer: Some say that using config resolver is bad practice, but for simpler usecases it is okay, IMO.
Have a look to our CjwPublishToolsBundle.
https://github.com/cjw-network/CjwPublishToolsBundle
https://github.com/cjw-network/CjwPublishToolsBundle/blob/master/Services/TwigConfigFunctionsService.php
Here we have 2 wrapper twig functions
{{cjw_config_resolver_get_parameter ( 'yamlvariablename', 'namespace default ezsettings') }}
=> ezpublish siteaccessmatching
{{cjw_config_get_parameter( 'mailer_transport' )}}
=> core symfony yaml reader without siteaccess
You could do a lot of things in eZ 4 and not always really good for your application design. ezini was able to read the configuration from the template but now in eZ Platform and by extension Symfony you need to respect more common patterns. IMO the view should not be that smart.
Then injecting variables to the view from a listener (PreContentViewListener or your own) is not a bad idea.
You can also use the Twig Globals that could allow you to do 2 global things:
inject variables (1)
inject a service (2)
Look here: https://symfony.com/doc/current/templating/global_variables.html
(2): please don't inject the service container globally it is bad
(1): I don't remember if the Twig Globals are Site Access aware, if not injecting your own service (2) to manage access to the config might be better.
And finally, I think that the use case is not a common one:
we used to use this to pass specific locations or id's with which we could then render certain content.
Most of the time it is a bad idea to pass ids coming from the configuration to render something, it is much better to organize the content structure to let you pull the location you want using the PHP API. (no id in configuration no hassle with dev, stage, preprod and prod architecture)

How to use us/en instead of en_US with JMSI18nRoutingBundle

I'm using JMSI18nRoutingBundle for locale routing on our new site, but our existing site uses language + country in the following format and I need to keep the URLs looking the same.
example.com/us/en/hello (en_US)
example.com/be/fr/bonjour (fr_BE)
Is there any way to do this using config? If not, where is the best place to start customizing?
It doesn't look it's possible to do through config, but it can be done by replacing default implementation of PatternGenerationStrategyInterface by your own implementation.
You can check out default implementation that bundle uses here.
After you create your own implementation, just make bundle use your own implementation by setting the config parameter. If you're using YAML for example:
parameters:
jms_i18n_routing.pattern_generation_strategy.class: YourBundle\YourImplementationClass
Hint: you can basically copy/paste from default implementation and change line 69 to use str_replace('_', '/', $locale) instead of just $locale. That way, newly generated route pattern will contain a / if locale contains an _.
Not very elegant solution, but bundle unfortunately doesn't provide enough configuration to make it prettier.

How to use the decoupled symfony components?

Any information on how to use symfony's decoupled components?
I'm rereading the docs but there's nothing on the topic besides a general message of "They are very very decoupled" and 1 tutorial that makes use of Request and Response.
There's also one badly ranked answer of Using symfony2 routing component (outside of symfony2)
Also having a look at a tutorial for the standalone Form component doesn't actually excite me how pleasant this is.
I need the routing, yaml, and session.
The first component you should use is ClassLoader. You can also use spl_autoload_register, but you're using Symfony, so why shouldn't you use its own autoloading library? Add the following at the top of the script:
use Symfony\Component\ClassLoader\UniversalClassLoader;
require_once '/path/to/symfony/src/Symfony/Component/ClassLoader/UniversalClassLoader.php';
$loader = new UniversalClassLoader();
$loader->register();
$loader->registerNamespaces(array(
'Symfony' => '/path/to/symfony/src',
));
Using the Yaml component is really easy:
use Symfony\Component\Yaml\Parser;
$data = Parser::parse('yaml string');
For the other components, you'll have to read the API documentation, as there are no tutorials yet.
Interestingly, Fabien Potencier just published a blog post which contains snippets of how to use the most common components. See the second half of this post for details.
I've written a tutorial which might help you, on using decoupled Symfony components in your project.
It shows how to use the console component as an example, but the logic is the same for other components.
Composer is the answer.
This video here http://www.youtube.com/watch?v=QOldVDVYnAE has a simple and straight forward step by step that answers your question.
EDIT on august 26th 2020: The video creator has made it private. Sorry, nothing I can do about it.
Symfony2 example
1) Install the component You need with composer in new folder
composer require symfony/yaml
2) Create the script yaml.php
<?php
require_once __DIR__.'/vendor/autoload.php';
use Symfony\Component\Yaml\Parser;
$yaml = new Parser();
$value = $yaml->parse('invoice: 3484');
var_dump($value);
3) Run the script
php yaml.php

Resources