Drupal 8 custom module add php classes - php

I have created a custom Drupal 8 module that works as is with a custom block and block form to collect some info.
This is all good.
I also have a twig template that I want to render a twitter feed using a php feed class I bought. I just don't know how it integrate this into the module.
This is the setup for the class: http://austinbrunkhorst.com/demos/twitter-class/#setup
It contains two files:
ultimate.twitter.feed.php
and
tmhOAuth.php
Which is currently a require_once 'tmhOAuth.php'; in the head of ultimate.twitter.feed.php
According to the instruction I should be creating a php file that has this:
$options = array(
'screen_name' => 'FeedTestUser',
'consumer_key' => '...',
'consumer_secret' => '...',
'user_token' => '...',
'user_secret' => '...',
);
$twitter = new Twitter($options);
$twitter->PrintFeed();
Which I'm guessing is also a hurdle as twig files are not php
Any help with this is very much appreciated.
C

I would setup the class as a Service in your module. Your block will then implement that service and do the handling. You don't really want to use require_once() if you can avoid it, rather use Drupal constructs (in part so that if you reorganize things later Drupal will help find the files in their new location).
Place the class in your module's src directory, and add a namespace to the start of the file (assuming there isn't one there already). Then in your block's class file you should be able to add a use statement that references that name space (even better would be to use a dependency injection, but the details on that would get in your way here).
In your block class's build() method you then instantiate the class as described in your question, but instead of just letting the module print HTML, you can want to capture that HTML and place it into your block as markup. If the class allows you to do that without using a buffer, you should (but I didn't see anything in the docs to support that), and then attempt to theme the structured data. If not, you can use PHP's output buffering to capture its attempt to print:
ob_start();
$twitter->PrintFeed();
$content= ob_get_contents();
ob_end_clean();
Then place the generated markup into a render array:
return [
'my_twitter_block' => [
'#markup' => $content,
],
];

Create a custom block and add the result of PrintFeed() to the render array. Just as with any usual custom block. In the render array you can specify a template which should be used (if needed). If you wanna output pure html without any template you could use the '#markup' key.
Small example:
Your block render array:
return array(
'#theme' => 'name_of_your_theme',
'#some_twig_variable' => $twitter->PrintFeed();
);
your your_module.module file (in the root of your module folder):
function your_module_theme() {
return array(
'name_of_your_theme' => array(
'variables' => array(
'some_twig_variable' => some-default-value,
),
),
);
}
your name-of-your-theme.html.twig template (should be under your_module/templates):
{{ some_twig_variable }}
As far as using the class: I see no problem using a require_once for that matter (in your Block php file). Of course it's always better/nicer if you can require the library/package via the make file or composer and then use the autoloader, but if that's not possible just put it e.g. in your drupal root under /libraries/twitter or so and then require it. If you do it like that you have to check that library into your git repository obviously.

have you use ultimate.twitter.feed.php in your TwitterBlock.php file
If not then try adding this line before class block beginns:
require_once 'path/to/twitter_class/ultimate.twitter.feed.php';

Related

PHP Sagepay iframe integration

I want to make my website payments via sagepay. The problem is I am not able to locate all the things in the PHPKit they provide. The version of the kit is 3.0 and I want to configure iframe integration but when I open the test method there is this piece of code
$view = new HelperView('server/low_profile');
$view->setData(array(
'env' => $this->sagepayConfig->getEnv(),
'vendorName' => $this->sagepayConfig->getVendorName(),
'integrationType' => $this->integrationType,
'request' => HelperCommon::getStore('txData'),
));
$view->render();
I want to locate those keys 'env', 'vendorName', 'integrationType', 'requests' and see how to put them to use in my system. I see this syntax in a lo of places
public function setSagepayConfig(SagepaySettings $sagepayConfig)
{
$this->sagepayConfig = $sagepayConfig;
}
But I don't know what SagepaySettings means and how to trace it. Can you tell me where can I find SagepaySettings, or what does this mean. Is it a class or method or attribute, because I cannot find it in all the files as any of those.
It's a class in \lib\classes\settings.php

How to include a separate file inside bootstrap.php that is meant for application wide constants and other application-wide Configure::write values?

I am using CakePHP3.
I prefer to put my application-wide PHP constants and Configure::write values inside a separate php file, usually called constants.php
And then at the end of the bootstrap.php, I will include this constants.php file.
I have no problems with the PHP constants. However, I have issues using Configure::write inside this separate file.
Is there a way to use Configure::write in a separate php file? I have tried using
use Cake\Core\Configure;
inside constants.php but I still get errors.
EDIT
Example of constants.php
<?php
/**
* provide all the kinds of site ID
*/
Configure::write('ADMINISTRATOR_SIDEBAR', array(
'quotations' => [
'link' => '/quotations',
],
'projects' => [
'sub_menu' => [
[
'title' => 'Project 1',
'icon' => '',
'link' => '/job_projects/view/5',
]
],
'link' => '/job_projects'
]
));
When I write that and then
require __DIR__ . '/constants.php';
in the last line of bootstrap.php
I get
Error: Class 'Configure' not found
File ...constants.php
Line: 8
When I then added use Cake\Core\Configure; at the top of constants.php, the error is removed.
Does this mean my issue is solved?
Do you have that many constants? Use class constants instead:
class UserType {
const ADMIN = 'admin';
const USER = 'user';
}
IMO it is better to keep them organized in classes than having tons of global constants. I dislike constants most of the time because you can't really never ever change them at run time. So this leaves just two use cases for them:
Things that should never ever change at runtime (which is rare)
Using them for "identifiers" instead of strings
Explaining 2. a little more: $userRole === 'admin' can fail because of a typo, you won't get an error and might end up with a pretty shitty to debug situation while doing $userRole === UserRole::ADMIN will throw an error if it is not present.
You're not showing any code, so no idea what you're doing wrong with Configure. Why are you not simply using Configure::load() and the `$config = []' array in the file you're going to load with that method?

How to get template source in php mustache engine

I am trying to get a raw template that is already loaded by Mustache_Engine. On creation of the mustache object Filesystem_Loader instance is set up and pointing to the default directory.
$mustache = new Mustache_Engine( array(
'loader' => new Mustache_Loader_FilesystemLoader( 'path-to-templates' )
) );
And later, for rendering the templates I use.
echo $mustache->render( 'template-name', $data );
The same template is used by mustache.js on server side, so i want to also print that template as inline script.
I could load the template from the filesystem manually with file_get_contents, but since that template is already loaded maybe there's a way to retrieve that from Mustache_Engine. Also, to use the file_get_contents i must use full path of the template and that just contradicts with the purpose of Mustache Template Loader.
After digging through the Mustache_Engine source, found the answer. getLoader() will get the current Mustache Template Loader instance, and load() function will load the template ( if is not already loaded ) and return it as string.
echo $mustache->getLoader()->load( 'template-name' );

ZF2 - How To Translate Zend Form Validation Error Messages?

I have the .po and compiled .mo language files for diffrent languages.
But language translation is not working on zend form validation error messages.
I dont want to use extra .php file like fr.php for it.
I got this code from click here
$translator = new Zend\I18n\Translator\Translator();
$translator->addTranslationFile(
'phpArray'
'resources/languages/en.php',
'default',
'en_US'
);
Zend\Validator\AbstractValidator::setDefaultTranslator($translator);
Any solution how to implement it in ZF2.
I do not approve of the selected answer :P
When adding a new translator to your configuration, do NOT use the default translator-text-domain. The Syntax is as follows:
$translator->addTranslationFile(
$type,
$resource,
$textDomain, //<-- this is the important one
$lang
);
In your example you've added a file to the default-textdomain. This, sadly, brings lots of troubles with it, at it will not always work as expected. Whenever you're adding translation files, add them to your own text-domain!
After that, all you need to do is to assign the Zend\Form\View\Helper your text-domain. This is done by the following:
// For Labels
$this->formLabel()->setTranslatorTextDomain('your-textdomain');
// For Buttons (input type submit)
$this->formButton()->setTranslatorTextDomain('your-textdomain');
// For Error-Messages
$this->formElementErrors()->setTranslatorTextDomain('your-textdomain');
How to get the ServiceManager into the Form?
This is pretty easy, too. The simples one is to use constructor-injection and inject the ServiceManager or ServiceLocator into the __construct() of your Form. On a Controller-Level this would look something like this:
$serviceLocator = $this->getServiceLocator();
$form = new My\Form($serviceLocator);
A more in-depth introduction to Form-Dependencies can be found on my Blog, where i illustrate the population of a Zend\Form\Element\Select-Element on dependent Database-Connections.
About the Translator itself
Another thing to note is: as long as there is a Translator-Service attached to your configuration with the name translator, it will automatically be attached to the form as default translator. This is a sample configuration i use within my modules regularly:
'translator' => array(
'locale' => 'de_DE',
'translation_file_patterns' => array(
array(
'type' => 'phparray',
'base_dir' => __DIR__ . '/lang',
'pattern' => '%s.php',
'text_domain' => __NAMESPACE__,
),
),
),
Simply add your .po or .mo files instead of the .php ones, i.e. like this:
$translator = new Zend\I18n\Translator\Translator();
$translator->addTranslationFile(
'gettext'
'resources/languages/fr.mo',
'default',
'fr_FR'
);
Zend\Validator\AbstractValidator::setDefaultTranslator($translator);
And then to translate it, use
echo $this->formElementErrors($form->get("username"),
array('message' => $this->translate("errormessage"))
);
I don't know how it is with performance of the translation in ZF2, but in ZF1 using arrays in .php files was way faster than any other method.

joomla 1.7 : override a module helper.php

I want to override a helper.php file of a module, exactly
\administrator\modules\mod_quickicon\helper.php
what I want is to update the getButtons function in this file
what are the options I have to override this particular file ? its possible using a plugin ?
thanks
You can really only do a template override on the file in the tmpl folder called default.php. If you want to override helper.php, you're essentially rewriting the module itself. This isn't necessarily a bad thing, just copy the contents of the existing helper.php file into another file for backup, and hack away. The downside of doing this is that if someone updates the module, and you install that update, you'll have to redo your hack. Again, it's not that hard to work around. Just backup backup backup.
Some more thoughts:
You could also do the following:
1) Copy the module to a different folder, beginning with mod_ as well, but with a different name.
2) Modify the xml file, helper file, component file (and any others that are necessary) to account for the new name. Also do whatever you want to helper.php.
3) Go to extension manager and do a discover install of this new module
4) Go to module manager and make a new instance of the new module (using the same position as the old one).
5) Unpublish the module you're replacing
Doing this will keep you safe from update loss.
Here is what I've done with Joomla! 3.3.1 but it might be done with Joomla! 1.7, too:
Copy default.php from
/administrator/modules/mod_quickicon/tmpl/
to
/administrator/templates/YOUR_ADMIN_TEMPLATE_NAME/html/mod_quickicon/
Open the copied file and replace the line below
$html = JHtml::_('links.linksgroups', ModQuickIconHelper::groupButtons($buttons));
with these lines:
$myLinks = array(
'YOUR_QUICKICON_GROUP_NAME' => array(
array(
'link' => JRoute::_('index.php?option=com_YOURCOMPONENT'),
'image' => 'stack',
'icon' => 'header/icon-48-article-add.png',
'text' => JText::_('YOUR_QUICKICON_ITEM_NAME'),
'access' => array('core.manage', 'com_YOURCOMPONENT'),
'group' => 'YOUR_QUICKICON_GROUP_NAME'
)
)
);
$array = ModQuickIconHelper::groupButtons($buttons);
$array = array_merge($myLinks, $array);
$html = JHtml::_('links.linksgroups', $array);
That's it. You can edit or create /administrator/language/overrides/en-GB.override.ini and add these lines:
YOUR_QUICKICON_GROUP_NAME="The Group"
YOUR_QUICKICON_ITEM_NAME="The Item"
Enjoy!

Categories