How to install (properly) ScnSocialAuth without using the SkeletonApp from ZF2 - zend-framework2

I read the README from https://github.com/SocalNick/ScnSocialAuth. I can not use the ZendSkeleton because I want to integrate it in an existing project.
I'm quiet new and the README does not answer some question, like
How do I integrate it with my zfc-user/login.phtml / register.phtml etc.?
What do I do after the last step in the README?
What page do I need to access to test if it works?
My problem is that the README has an abrupt end and leaves me in the dark about how to use/access it.
However, I followed all the steps in the README and end up with the following error:
PHP Fatal error: Call to a member function getEnabledProviders() on a non-object in /view/zfc-user/user/login.phtml on line 3
My zfc-user/login.phtml
<?php
$socialSignIn = true;
foreach ($this->options->getEnabledProviders() as $provider) {
if ($socialSignIn) {
echo '<h1>Social Sign In</h1>';
$socialSignIn = false;
}
echo '<dd>' . $this->socialSignInButton($provider, $this->redirect) . '</dd>';
}
if ($this->options->getSocialLoginOnly() == false) {
echo $this->zfcUserLogin;
}
?>
application.config.php
'modules' => array(
'Application',
'ScnSocialAuth',
'ZfcBase',
'ZfcUser'
...
composer.json
"require": {
"php": ">=5.3.3",
"zendframework/zendframework": "2.*",
"zendframework/zend-diactoros": "*",
"zf-commons/zfc-base": "*",
"zf-commons/zfc-user": "1.2.*",
"neilime/zf2-twb-bundle": "*",
"symfony/yaml": "*",
"snapshotpl/zf-snap-jquery": "dev-master",
"zendframework/zendservice-recaptcha": "2.*",
"socalnick/scn-social-auth": "1.*"
},
"autoload": {
"psr-0": {
"Hybrid": "vendor/hybridauth/hybridauth/hybridauth/"
}
}
composers autoload_namespaces.php
return array(
'phpDocumentor' => array($vendorDir . '/phpdocumentor/reflection-docblock/src'),
'ZfcUser' => array($vendorDir . '/zf-commons/zfc-user/src'),
'ZfcBase' => array($vendorDir . '/zf-commons/zfc-base/src'),
'ZfSnapJquery' => array($vendorDir . '/snapshotpl/zf-snap-jquery/src'),
'ZendXml' => array($vendorDir . '/zendframework/zendxml/library'),
'ZendService' => array($vendorDir . '/zendframework/zendservice-recaptcha/library'),
'TwbBundle' => array($vendorDir . '/neilime/zf2-twb-bundle/src'),
'ScnSocialAuthTest' => array($vendorDir . '/socalnick/scn-social-auth/test'),
'ScnSocialAuth' => array($vendorDir . '/socalnick/scn-social-auth/src'),
'Prophecy\\' => array($vendorDir . '/phpspec/prophecy/src'),
'Hybrid' => array($vendorDir . '/hybridauth/hybridauth/hybridauth', $vendorDir . '/hybridauth/hybridauth/hybridauth'),
);
Do I miss something in the docs or is it just the heat that's screwing with my head?

Related

Yii2: GridView: add button or link to controller action

I have a controller with an action method:
namespace frontend\controllers;
class EmployeeController extends FrontController
{
/**
* Deletes an existing Employee status.
* #param integer $id
* #return mixed
*/
public function actionDeleteStatus($status_id)
{
error_log("actionDeleteStatus " . $status_id);
return $this->redirect(['update']);
}
}
In update form, I have a detail GridView, in which I want to add a "delete" link with an URL for this method as a GET request.
I try to get the URL with this: Url::toRoute(['employee/deleteStatus','status_id' => $model->status_id]) which gives me an url like /employee/deleteStatus?status_id=4 and throws a 404, here is the detailed code:
<div class="col-xs-12">
<?php
echo Html::label(Yii::t('app', 'Employee status history'));
echo GridView::widget([
'summary' => '',
'options' => [
'id' => 'status-history',
],
'emptyText' => '',
'export' => false,
'dataProvider' => $statusHistory,
'columns' => [
[...],
[
'class' => 'kartik\grid\DataColumn',
'attribute' => 'status_id',
'headerOptions' => [ 'class' => 'kv-grid-hide' ],
'contentOptions' => [ 'class' => 'kv-grid-hide' ]
],
[
'class' => 'yii\grid\ActionColumn',
'urlCreator' => function($action, $model, $key, $index) {
return Url::toRoute(['employee/deleteStatus','status_id' => $model->status_id]);
},
'template' => '{delete}',
'contentOptions' => ['class' => 'column-action'],
'buttons' => [
'delete' => function ($url, $model, $key) {
if (Yii::$app->user->can('globalDAF')) {
$options = [
'title' => Yii::t('app', 'Delete'),
'aria-label' => Yii::t('app', 'Delete'),
'data-confirm' => Yii::t('app', 'Sure to delete status?'),
'data-method' => 'post',
'data-pjax' => '0',
'class' => 'btn-llyc'
];
return Html::a('<span class="glyphicon glyphicon-remove"></span>', $url, $options);
} else {
return;
}
}
]
]
],
'hover' => true,
'responsiveWrap' => false
]);
?>
</div>
Is the url generation wrong? Why am I getting a 404?
Thanks.
For example, index becomes actionIndex, and hello-world becomes
actionHelloWorld.
Note: The names of the action methods are case-sensitive. If you have
a method named ActionIndex, it will not be considered as an action
method, and as a result, the request for the index action will result
in an exception. Also note that action methods must be public. A
private or protected method does NOT define an inline action.
Link
Url::toRoute(['employee/delete-status','status_id' => $model->status_id])
Or in config file:
'urlManager' => [
'class' => 'yii\web\UrlManager',
#code ..
'rules' => [
'employee/deleteStatus' => 'employee/delete-status',
],
],

Yii2 Multiple Variables to be passed in URL

I want to generate URL's that can handle multiple parameters.
Eg:
www.example.com/product/index?brand=brand-name,
www.example.com/product/index?category=category-name,
I want the url be like :
www.example.com/brand-name,
www.example.com/category-name
Tried some url rules,but it doesn't work.
'rules' => [
[
'pattern' => '<brand:\w+(-\w+)*>/<category:\w+(-\w+)*>',
'route' => 'product/index',
'defaults' => [
'brand' => null,
'category' => null,
]
]
]
This is my reference :
Reference question
To do this you will have to stick to the prefixed version. So the brand param should always be prefixed with brand- and the category always with category-. Otherwise there is no way to tell what is what.
Add the following rules. This will put everything that matches brand-\w+ in the brand argument and pass it to product/index. Same for category.
'<brand:brand-\w+>' => 'product/index',
'<category:category-\w+>' => 'product/index',
To see that it works
public function actionIndex($brand = null, $category = null) {
echo "Brand: $brand<br />";
echo "Category: $category<br />";
echo Url::toRoute(['dev/index', 'brand' => 'brand-name']) . '<br />';
echo Url::toRoute(['dev/index', 'category' => 'category-name']) . '<br />';
}

Translating navigation breadcrumbs

I'm trying to translate the breadcrumbs sitting in the module/Application/config/module.config.php configuration file like:
'navigation' => array(
'default' => array(
array(
'label' => \Application\Util\Translator::translate('Home'),
'route' => 'home',
'resource' => 'route/home',
'pages' => array(
),
),
The breadcrumb Home should display as Accueil in french.
The translator works just fine for the rest of the application. But none of the breadcrumbs are translated. The language resource file has been verified and poedit-ed again and again.
In the very same configuration file, is the translator
configuration:
'service_manager' => array(
'factories' => array(
'account_navigation' => 'Application\Navigation\Service\AccountNavigationFactory',
'navigation' => 'Zend\Navigation\Service\DefaultNavigationFactory',
'translator' => 'Zend\I18n\Translator\TranslatorServiceFactory',
'Application\Collector\RouteCollector' => 'Application\Service\RouteCollectorServiceFactory',
),
),
'translator' => array(
'locale' => 'fr_FR', // langue par défaut
'translation_file_patterns' => array(
array(
'type' => 'gettext',
'base_dir' => __DIR__ . '/../language',
'pattern' => '%s.mo',
),
),
'translation_files' => array(
array(
'type' => 'phpArray',
'filename' => __DIR__ . '/../../../vendor/zendframework/zendframework/resources/languages/fr/Zend_Validate.php',
'locale' => 'fr_FR'
),
array(
'type' => 'gettext',
'filename' => __DIR__ . '/../../../vendor/zf-commons/zfc-user/src/ZfcUser/language/fr_FR.mo',
'locale' => 'fr_FR'
),
array(
'type' => 'phpArray',
'filename' => __DIR__ . '/../language/fr_FR.php',
'locale' => 'fr_FR'
)
)
),
My application bootstrap looks like:
class Module
{
public function onBootstrap(MvcEvent $e)
{
$eventManager = $e->getApplication()->getEventManager();
$moduleRouteListener = new ModuleRouteListener();
$sm = $e->getParam('application')->getServiceManager();
// Add ACL information to the Navigation view helper
$authorize = $sm->get('BjyAuthorize\Service\Authorize');
$acl = $authorize->getAcl();
$role = $authorize->getIdentity();
\Zend\View\Helper\Navigation::setDefaultAcl($acl);
\Zend\View\Helper\Navigation::setDefaultRole($role);
$id = $sm->get('zfcuser_auth_service')->getIdentity();
if (! is_null($id)) {
$em = $sm->get('Doctrine\ORM\EntityManager');
$usr = $em->find('Application\Entity\User', $id->getId());
$blameableListener = new \Gedmo\Blameable\BlameableListener();
$blameableListener->setUserValue($usr);
$em->getEventManager()->addEventSubscriber($blameableListener);
} else {
// redirection
if (isset($_SERVER['SERVER_NAME']) && preg_match('/monxxxxx/', $_SERVER['SERVER_NAME'])) {
$strategy = new RedirectionStrategy();
$strategy->setRedirectRoute('driver/login');
$eventManager->attach($strategy);
}
}
if ($sm->has('MvcTranslator')) {
\Zend\Validator\AbstractValidator::setDefaultTranslator($sm->get('MvcTranslator'));
}
Locale::setDefault('fr_FR');
// custom layout
$e->getApplication()->getEventManager()->getSharedManager()->attach('Zend\Mvc\Controller\AbstractController', 'dispatch', function($e) {
$route = $e->getRouteMatch();
$controller = $e->getTarget();
// change layout for login
if($route->getParam('controller') == 'zfcuser' && $route->getParam('action') == 'login'){
$controller->layout('layout/login');
}
}, 100);
// Log the exceptions
$application = $e->getApplication();
$sm = $application->getServiceManager();
$sharedManager = $application->getEventManager()->getSharedManager();
$sharedManager->attach('Zend\Mvc\Application', 'dispatch.error',
function($e) use ($sm) {
if ($e->getParam('exception') && strpos($e->getParam('exception'), 'are not authorized') === false) {
$sm->get('Zend\Log\Logger')->crit($e->getParam('exception'));
$toEmail = "xxxxx#xxxxx.com";
$toName = "Service IT";
$subject = "Exception error";
$body = $e->getParam('exception');
\Application\Util\Common::sendMail($toEmail, $toName, $subject, $body);
}
}
);
}
public function getConfig()
{
return include __DIR__ . '/config/module.config.php';
}
public function getAutoloaderConfig()
{
return array(
'Zend\Loader\StandardAutoloader' => array(
'namespaces' => array(
__NAMESPACE__ => __DIR__ . '/src/' . __NAMESPACE__
)
)
);
}
public function init($moduleManager)
{
$moduleManager->loadModule('ZfcUser');
}
}
I'm on ZF2 2.2.5.
Might be a silly question, but do you have the PHP gettext module (verified via your phpinfo())? If yes, you could much easier use _('Translatable string') for strings needing translation. You'd have a .mo and .po file in a language folder (next to src, public, etc.).
(Asking the above because you seem to be putting a lot of effort into this, even though your code shows you use gettext as a translator, which should allow you to already translate static strings, such as home in a config file)
As an example the picture below, it is the basic setup for one of my own ZF2 vendor modules:
Next, you'd need Poedit (Free version should be plenty.).
NOTE: Make sure to always use Poedit to edit the .mo/.po files.
Use Poedit to open the files in the language folder, no need to "translate" strings that are the same string as the language they should be, unless you're using shortcuts for strings (ie. "index" string should display "Show overview", but please don't :p)
Within Poedit you have a few options to add additional strings that it searches for in your files and you can also add additional file extensions. I would suggest you have it look for these strings:
$this->translate()
_()
and these file extensions:
.php
.phtml
That way you've covered the basics. Of course your setup may be different, so modify as needed.
Lastly, you need to register the usage of gettext PHP extensions in you module config. You need to do this for every module, as you need to give a language folder path, as that is where your module 'should' be translated (though feel free to make it global and have a huge translation file if you must, not recommended).
Add the following bit to your module.config.php file:
'translator' => [
'locale' => 'en_US', // This line needs to be in the "root" config, feel free to override with/per module settings and/or user settings
'translation_file_patterns' => [
[
'type' => 'gettext',
'base_dir' => __DIR__ . '/../language',
'pattern' => '%s.mo',
],
],
],
With all of the above, translating your breadcrumbs should be done like so:
'navigation' => array(
'default' => array(
array(
'label' => _('Home'),
'route' => 'home',
'resource' => 'route/home',
'pages' => array(
),
),
It seems that namespace Zend\View\Helper\Navigation\Breadcrumbs; is not instanciated correctly in your service manager. Therefore, the translator will not work because it also provided by the service manager as a dependancy
What you should do is to verify if Zend\View\Helper\Navigation\Breadcrumbs::line#113 is actually parsed when you load your breadcrumbs. At least this one.
You can also check the method htmlify of AbstractHelper to test if the translator is enabled.

zend 2 including custom library old style

I have custom libs in old style zend. I mean:
/home/my/libs/StandardTypes/UF.php
class StandardTypes_UF{
...
}
I've tried use this in Zend 2
I tried this codes:
//init_autoloader.php
...
include $zf2Path . '/Zend/Loader/AutoloaderFactory.php';
Zend\Loader\AutoloaderFactory::factory(array(
'Zend\Loader\StandardAutoloader' => array(
'autoregister_zf' => true,
'prefixes' => array(
'StantardTypes' => '/home/my/libs/StandardTypes',
),
)
));
...
//controller
$st = new \StantardTypes_UF();
I have this error: Fatal error: Class 'Beneficio\Controller\StantardTypes_UF' not found
I tried this way too:
//Module.php
...
public function getAutoloaderConfig(){
return array(
'Zend\Loader\StandardAutoloader' => array(
'namespaces' => array(
__NAMESPACE__ => __DIR__ . '/src/' . __NAMESPACE__,
),
'prefixes' => array(
'StantardTypes' => '/home/my/libs/StandardTypes',
),
),
);
}
...
I have the same error.
I cant change the libs to new style, first cuz it is too big, secund cuz it's used in old projects too.
Any ideia how to solve this?
The problem is that I can't use a path out of the project. I put the lib StandardTypes in vendor path and it works!
...
'prefixes' => array(
'StantardTypes' => '/home/my/project/vendor/StandardTypes',
),
....

How to access custom view helper in a partial?

Is there a way to access a custom view helper registered in my module like this:
'fooBar' => 'Library\FooBar\FooBar'
like this?
<p>This is partial...</p>
<p><?php echo $this->fooBar(); ?></p>
I can use the fooBar view helper in views but in partials I get an error. Here is my view helper:
class FooBar extends AbstractHelper
{
public function __invoke($module)
{
return $this->getView()->myMethod();
}
}
And I am getting an error along the lines:
Call to a member function myMethod() on a non-object
it is working for me. I configure view helper in Module.php file something like this.
//module/src/module/View/Helper/Authz.php
// view helper
use Zend\View\Helper\AbstractHelper;
class Authz extends AbstractHelper
{
public function isAllowed()
{
}
}
.
//Module.php
public function bootstrap(Event $e)
{
}
public function onBootstrap($e)
{
$app = $e->getApplication();
$serviceManager = $app->getServiceManager();
$serviceManager->get('viewhelpermanager')->setFactory('Authz', function ($sm) use ($e) {
return new Authz($sm); //view helper
});
}
// partial
// view/layout/partials/leftnav.phtml
$userAllow = $this->Authz()->isAllowed();
// in layout i call above leftnav.phtml partial something like this.
//view/layout/layout.phtml
<?php echo $this->partial('partials/header', array('company_name' => 'CompanyName')); ?>
// config/module.config.php
'view_manager' => array(
'template_path_stack' => array(
'modulename' => __DIR__ . '/../view' ,
),
'strategies' => array(
'ViewJsonStrategy',
),
'display_not_found_reason' => true,
'display_exceptions' => true,
'doctype' => 'HTML5',
'not_found_template' => 'error/404',
'exception_template' => 'error/index',
'template_map' => array(
'layout/layout' => __DIR__ . '/../view/layout/layout.phtml',
'partials/header' => __DIR__ . '/../view/layout/partials/header.phtml',
'partials/leftnav' => __DIR__ . '/../view/layout/partials/leftnav.phtml',
'partials/contents-top' => __DIR__ . '/../view/layout/partials/contents-top.phtml',
'error/404' => __DIR__ . '/../view/error/404.phtml',
'error/index' => __DIR__ . '/../view/error/index.phtml',
),
),

Resources