DbTableGateway is not writing my session information to database table - zend-framework2

I'm trying to use DbTableGateway to store my session information in a MySQL database--but my "sessions" table is remaining empty. It never contains any rows. Here's my code (more or less copy/pasted from here):
$dbAdapter = new Zend\Db\Adapter\Adapter(array(
'driver' => 'pdo_mysql',
'database' => 'db-name',
'username' => 'username',
'password' => 'password!'
));
$tableGateway = new \Zend\Db\TableGateway\TableGateway('session', $dbAdapter);
$saveHandler = new \Zend\Session\SaveHandler\DbTableGateway($tableGateway, new \Zend\Session\SaveHandler\DbTableGatewayOptions());
$manager = new \Zend\Session\SessionManager();
$manager->setSaveHandler($saveHandler);
$someContainer = new Container('SomeSessionNamespace');
$someContainer->aBitOfData = 'tasty morsel of data';
And here's a video demonstration of me using this code:
http://screencast.com/t/UDDUs6OZOib
As you can see in the video, session information is preserved between requests, but it's not being stored in the database.
I added breakpoints to every function in Zend\Session\SaveHandler\DbTableGateway, and the only one that's getting hit is in __constructor. So the constructor is getting called, but apparently it never gets used for anything else.
What am I missing?
I'm using Zend Framework 2.2.2 on PHP 5.3.
-Josh

I found some modules to do that if you need to implement this quickly
https://github.com/Nitecon/DBSessionStorage
https://github.com/gabriel403/G403SessionDb
To use your current code, please check:
options of ** DbTableGatewayOptions** (id, data, lifetime, etc..)
$options = new \Zend\Session\SaveHandler\DbTableGatewayOptions();
$options->setDataColumn('data');
$options->setIdColumn('id');
$options->setLifetimeColumn('lifetime');
$options->setNameColumn('name');
$options->setModifiedColumn('modified');
the start of you SessionManager $manager->start();

Check in application.config.php and make sure the Application module is at the top level
Also make sure that in
'vendor/composer/autoload_namespaces.php' and
'vendor/composer/autoload_static.php'
zend and zendxml library path added or not
eg : 'Zend' => array(vendorDir . '/ZF2/library'),
'ZendXml' => array(vendorDir . '/ZF2/library')

Related

TYPO3 - Retrieved TypoScript in itemsProcFunc are incomplete

I have following problem:
We are overriding the tt_content TCA with a custom column which has an itemsProcFunc in it's config. In the function we try to retrieve the TypoScript-Settings, so we can display the items dynamically. The problem is: In the function we don't receive all the TypoScript-Settings, which are included but only some.
'itemsProcFunc' => 'Vendor\Ext\Backend\Hooks\TcaHook->addFields',
class TcaHook
{
public function addFields($config){
$objectManager = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Extbase\\Object\\ObjectManager');
$configurationManager = $objectManager->get('TYPO3\\CMS\\Extbase\\Configuration\\ConfigurationManagerInterface');
$setup = $configurationManager->getConfiguration(
\TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface::CONFIGURATION_TYPE_FULL_TYPOSCRIPT
);
}
$setup is now incomplete and doesn't contain the full TypoScript, for example some of the static-included TypoScript is missing.
Used TYPO3 7 LTS (7.6.18), PHP 7.0.* in composer-mode.
Does anybody know where the problem is? Is there some alternative?
You maybe misunderstood the purpose of TypoScipt. It is a way of configuration for the Frontend. The Hook you mentioned is used in the TCA, whích is a Backend part of TYPO3. TypoScript usually isn't used for backend related stuff at all, because it is bound to a specific page template record. Instead in the backend, there is the TSConfig, that can be bound to a page, but also can be added globally. Another thing you are doing wrong is the use of the ObjectManager and the ConfigurationManager, which are classes of extbase, which isn't initialized in the backend. I would recommend to not use extbase in TCA, because the TCA is cached and loaded for every page request. Instead use TSConfig or give your configuration settings directly to the TCA. Do not initialize extbase and do not use extbase classes in these hooks.
Depending on what you want to configure via TypoScript, you may want to do something like this:
'config' => [
'type' => 'select',
'renderType' => 'singleSelect',
'items' => [
['EXT:my_ext/Resources/Private/Language/locallang_db.xlf:myfield.I.0', '']
],
'itemsProcFunc' => \VENDOR\MyExt\UserFunctions\FormEngine\TypeSelectProcFunc::class . '->fillSelect',
'customSetting' => 'somesetting'
]
and then access it in your class:
class TypeSelectProcFunc{
public function fillSelect(&$params){
if( $params['customSetting'] === 'somesetting' ){
$params['items'][] = ['New item',1];
}
}
}
I had a similar problem (also with itemsProcFunc and retrieving TypoScript). In my case, the current page ID of the selected backend page was not known to the ConfigurationManager. Because of this it used the page id of the root page (e.g. 1) and some TypoScript templates were not loaded.
However, before we look at the solution, Euli made some good points in his answer:
Do not use extbase configuration manager in TCA functions
Use TSconfig instead of TypoScript for backend configuration
You may like to ask another question what you are trying to do specifically and why you need TypoScript in BE context.
For completeness sake, I tested this workaround, but I wouldn't recommend it because of the mentioned reasons and because I am not sure if this is best practice. (I only used it because I was patching an extension which was already using TypoScript in the TCA and I wanted to find out why it wasn't working. I will probably rework this part entirely.)
I am posting this in the hope that it may be helpful for similar problems.
public function populateItemsProcFunc(array &$config): array
{
// workaround to set current page id for BackendConfigurationManager
$_GET['id'] = $this->getPageId((int)($config['flexParentDatabaseRow']['pid'] ?? 0));
$objectManager = GeneralUtility::makeInstance(ObjectManager::class);
$configurationManager = $objectManager->get(BackendConfigurationManager::class);
$setting = $configurationManager->getTypoScriptSetup();
$templates = $setting['plugin.']['tx_rssdisplay.']['settings.']['templates.'] ?? [];
// ... some code removed
}
protected function getPageId(int $pid): int
{
if ($pid > 0) {
return $pid;
}
$row = BackendUtility::getRecord('tt_content', abs($pid), 'uid,pid');
return $row['pid'];
}
The function getPageId() was derived from ext:news which also uses this in an itemsProcFunc but it then retrieves configuration from TSconfig. You may want to also look at that for an example: ext:news GeorgRinger\News\Hooks\ItemsProcFunc::user_templateLayout
If you look at the code in the TYPO3 core, it will try to get the current page id from
(int)GeneralUtility::_GP('id');
https://github.com/TYPO3/TYPO3.CMS/blob/90fa470e37d013769648a17a266eb3072dea4f56/typo3/sysext/extbase/Classes/Configuration/BackendConfigurationManager.php#L132
This will usually be set, but in an itemsProcFunc it may not (which was the case for me in TYPO3 10.4.14).

Yii1, prettry url issue

I want to make url like this in Yii1 http://example.com/customer-name. It would list jobs for the customer-name, this customer-name will be changing dynamically for example customer-name can be
customer-name=IBM or customer-name=abc-mn or customer-name=xyz
The urls will be something like this
http://example.com/IBM
http://example.com/abc-mn
http://example.com/xyz
I have tried many tutorials but when I a try nothing works for me. Also I followed the http://www.yiiframework.com/doc/guide/1.1/en/topics.url
You new to configure the main.php config properly and have your controller action ready.
private/protected/config/main.php
'urlManager'=>array(
//path is slash separated format aka www.url.com/controller/action/getparam/getvalue
'urlFormat'=>'path',
'showScriptName'=>false,
'caseSensitive'=>true,
'rules'=>array(
//site is your controller, comapny is your action and the name is get variable actionCompany is waiting for.
'<name>' => 'site/company'
)),
private/protected/controllers/SiteController.php (alos make sure the actioname company is in accessRules if you user acceessControll filter).
public function actionCompany( $name )
{
/* your action code */
$this->render('test', array( 'test' => 'to_view' ) );
}
If this didn't help then you have to give us more of your code.

Youtube Channel Gallery getting no longer supported video from YouTube

Suddenly the feed on our homepage has the - This device is no longer supported - video from YouTube. Everyone is seeing this no matter what device they are on, so we think it doesn't like something about the plugin now after YouTube changed and knew they would not be seen on certain devices and televisions: https://youtube.com/devicesupport
What is the fix for this? Are you pushing out an update to address this? Thanks.
https://wordpress.org/plugins/youtube-channel-gallery/
I would recommend taking a read through this thread in the support forum for the plugin:
https://wordpress.org/support/topic/getting-no-longer-supported-video-from-youtube
There are some different solutions, depending on whether you are using the widget or shortcode, but a few different approaches came up depending on what is easiest for you - personally, I favor this one:
open the file wp-content/plugins/youtube-channel-gallery.php
goto line 622 and paste this (directly under the foreach-line): if ($entry->title == 'https://youtube.com/devicesupport') { continue; }
let the plugin display 1 more video than before (maxitems)
What it does is: just throws away the "device support" video from the video feed. so there's one video less now, this is why you have to add 1 to the maxitems.
*Credit goes to Wordpress.org forums member "koem"
I had the same issue for the youtube videos and I fixed as follows:
After the installation of the youtube plugin in our site, we can see that the folder with the file name youtube-feeder.php
There is a function named "getFeedUrl" and this function is calling from the function
So the line is:
$dataURL ="To get the above URL please follow the below step";
https://developers.google.com/apis-explorer/#p/youtube/v3/youtube.channels.list
put the part as contentDetails and forUsername as [channel id] eg:Google
then execute then find the "uploads": "UUK8sQmJBp8GCxrOtXWBpyEA" from the list (ID will be different for your channel)
then go to the following:
https://developers.google.com/apis-explorer/#p/youtube/v3/youtube.playlistItems.list
Then put the part as snippet and paste the copied uploads id in the playlistId then execute. you can see the result and you just copy the Request URL from the result.
Note: you need to register your application for API_KEY
developers.google.com/youtube/registering_an_application
Second:
You need to change the parsing section also:
OLD code:
$entries = array();
if($data && is_array($data['feed']['entry']))
{
foreach($data['feed']['entry'] as $vid)
{
$vid = $vid['media$group'];
$url = $vid['media$content'][0]['url'];
$url = substr($url, 0, stripos($url, '?'));
$entries[] = array(
'id' => $vid['yt$videoid']['$t'],
'url' => $url,
'title' => $vid['media$title']['$t'],
'date' => $vid['yt$uploaded']['$t'],
'content' => $vid['media$description']['$t']
);
}
}
New Modification:
$entries = array();
if($data && is_array($data['items']))
{
foreach($data['items'] as $vid)
{
//var_dump($data['items']);
$vid = $vid['snippet'];
$url = "https://www.youtube.com/watch?v="+$vid['resourceId']['videoId'];
//$url = substr($url, 0, stripos($url, '?'));
$entries[] = array(
'id' => $vid['resourceId']['videoId'],
'url' => $url,
'title' => $vid['title'],
'date' => $vid['publishedAt'],
'content' => $vid['description']
);
}
}
Then check it out, If its not coming the exact data, please comment the following line also.
`if(!$entries = $this->getCachedYoutubeData($id, $cache, $type, $orderby))`
Please write here if you have.
Youtube API 3 is very different from API 2. I just switched plugins - wpyoutubevideogallery.com - easy to setup and fully functional with youtube API 3. Also free.

Twitter Module - Drupal 7

Twitter Module is working finde with my Drupal 7 site. I wanted to make a tweek so that nodes that are not hidden get tweeted, I was able to do this by altering twitter_post_node_insert in twitter/twitter_post . All I did was add a new condition of !$node->hidden . It works great.
function twitter_post_node_insert($node) {
if (!empty($node->status) && !empty($node->twitter) && !empty($node->twitter['post'])
&& !$node->hidden) { ......
My problem is that this code in the Twitter Module only gets called when I directly edit a node and save it. Now, I would like to have said code called also when I edit my node programmatically, where I save it with $node_wrapper->save(); . The twitter code won't get called. I've also tried with node_save($node); , instead of using my $node_wrapper. Nothing.
I also tried including the file twitter_post.module located in twitter/twitter_post, and then calling the function in charge of posting the tweet :
module_load_include('module', 'twitter', '../twitter/twitter_post/twitter_post');
twitter_post_node_update($node);
Nothing happens and no errors are shown. What I'd like is to know what Drupal 7 function gets called in its core when you edit a node through its interface and then save it. That way I can just put that function in the code where I edit my node programmatically so that the Twitter code will also get called. Or, does anyone have a better approach?
Thanks.
After looking into the Twitter module this is what I have done in order to have the nodes published programmatically.
I added the following function to twitter/twitter_post/twitter_post.module . It's a copy of the function function twitter_post_node_insert($node), found on the same file. I made a copy so that it would not print out the message of "tweet posted succesfully". That way I call the copied function from another place to post the tweet.
/**
* Function called from custom .module to insert tweets from "Editar Pesos" tab
*/
function twitter_post_node_custom_insert($node) {
if (!empty($node->status) && !empty($node->twitter) && !empty($node->twitter['post']) && !$node->hidden ) {
module_load_include('inc', 'twitter');
$twitter_account = twitter_account_load($node->twitter['account']);
$replacements = array(
'!title' => truncate_utf8($node->title, 90, false, true),
'!url' => url('node/' . $node->nid, array('absolute' => TRUE, 'alias' => TRUE)),
'!url-alias' => url('node/' . $node->nid, array('absolute' => TRUE))
);
// Only generate the shortened URL if it's going to be used. No sense
// burning through TinyURLs without a good reason.
if (strstr($node->twitter['status'], '!tinyurl') !== FALSE) {
$replacements['!tinyurl'] = twitter_shorten_url(url('node/' . $node->nid,
array('absolute'=> TRUE)));
}
$status = strtr($node->twitter['status'], $replacements);
return twitter_set_status($twitter_account, $status);
}
}
And following is the "magic", which gets called whenever I want the node posted as a tweet.
function post_to_twitter($node){
module_load_include('module', 'twitter', '../twitter/twitter_post/twitter_post');
$twitter = array(
'account' => getTwitterUid(),
'post' => 'POST',
'status' => "!title !tinyurl"
);
$node->twitter = $twitter;
return twitter_post_node_custom_insert($node);
}
function getTwitterUid(){
return db_query("select twitter_uid from {twitter_account} where screen_name = :screen_name
limit 1", array(":screen_name" => 'YOUR_TwitterScreenName'))->fetchField();
}
Hope this can help anyone who was looking for the same thing as I.

Symfony: issue with switching context

I am using Symfony 1.2 and I have some issues switching context.
This code was working fine:
require_once(dirname(__FILE__).'/../config/ProjectConfiguration.class.php');
$configuration = ProjectConfiguration::getApplicationConfiguration('account', 'prod', false);
$context = sfContext::createInstance($configuration, 'account-prod');
$userToLogin = PcUserPeer::retrieveByEmailAddress("myemail#example.com");
Auth::login($context->getUser(), $userToLogin, false, false);
echo "all done.";
At some point requirements changed and I needed to use the 'public' application before the 'account' one.
Then I changed to:
require_once(dirname(__FILE__).'/../config/ProjectConfiguration.class.php');
// {{{ new code:
$configuration = ProjectConfiguration::getApplicationConfiguration('public', 'prod', false);
sfContext::createInstance($configuration);
// some code using the public app...
// }}}
$configuration = ProjectConfiguration::getApplicationConfiguration('account', 'prod', false);
$context = sfContext::createInstance($configuration, 'account-prod');
// {{{ new code:
sfContext::switchTo('account-prod');
// }}}
$userToLogin = PcUserPeer::retrieveByEmailAddress("myemail#example.com");
CustomAuth::login($context->getUser(), $userToLogin, false, false);
echo "all done.";
Basically I added a switchTo call.
After the change, the code got broken and the error message is this:
PHP Fatal error: Call to a member function prepare() on a non-object in /var/www/html/myproj/symfony/storage/sfPDOSessionStorage.class.php on line 109
Thanks for your help,
Dan
Symfony is trying to load the session storage object. I suppose there is a problem with your new environment's configuration.
Check
/apps/public/config/factories.yml
Look for "storage" and try to find out how is it different from the other app's configuration.
Hard to know without a backtrace/more info what is triggering the error. It looks like you are using sessions stored in a database, and that a query related to that is failing.
Try setting the third argument to getApplicationConfiguration to true (which will turn debug on) and see if you get more output.
At a guess, it looks like the account app is using PDO session storage, and is failing to connect to the database or something?

Resources