I'm working a reasonably large zf1 project with multiple modules. We need to store the session state in the database for a new deployment. After a quick google we came across Zend_Session_SaveHandler_DbTable and followed the simple example (almost exactly) at http://framework.zend.com/manual/1.12/en/zend.session.savehandler.dbtable.html . I've placed the code in our application/Bootstrap.php and have checked it runs. However the database table is never populated with session data.
I thought something would be overriding the Zend_Session::setSaveHandler later in the code base but I can not find any other calls to that or Zend_Session::start();
Any suggestions on what might be wrong or how to investigate further?
edit with updated information:
here's how the relevant section of the bootstrap appears, currently just set up for dev mode.
protected function _initSessionDB()
{
$db = Zend_Db::factory('Pdo_Mysql', array(
'host' =>'localhost',
'username' => '****',
'password' => '****',
'dbname' => '****'
));
Zend_Db_Table_Abstract::setDefaultAdapter($db);
$config = array(
'name' => 'session_state',
'primary' => 'id',
'modifiedColumn' => 'modified',
'dataColumn' => 'data',
'lifetimeColumn' => 'lifetime'
);
Zend_Session::setSaveHandler(new Zend_Session_SaveHandler_DbTable($config));
Zend_Session::start();
}
and the database has
mysql> explain session_state;
+----------+----------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+----------+----------+------+-----+---------+-------+
| id | char(32) | YES | | NULL | |
| modified | int(11) | YES | | NULL | |
| lifetime | int(11) | YES | | NULL | |
| data | text | YES | | NULL | |
+----------+----------+------+-----+---------+-------+
4 rows in set (0.00 sec)
So turns out that the application I was working on sets up the FlashMessenger controller helper in the application/Bootstrap.
protected function _initAutoload()
{
Zend_Controller_Action_HelperBroker::addHelper(
new Zend_Controller_Action_Helper_FlashMessenger());
}
The FlashMessenger action helper makes its own call to Zend_Session::start(); which seems to take priority over any later calls.
Simple solution is to add a $this->bootstrap('sessionDB'); call before the FlashMessenger is created. for example,
protected function initFlashMessenger()
{
$this->bootstrap('sessionDB');
if (APPLICATION_ENV != 'testing')
Zend_Controller_Action_HelperBroker::addHelper(
new Zend_Controller_Action_Helper_FlashMessenger());
}
A better solution would be to not create the FlashMessenger in the bootstrap at all and just create it within controllers or appropriate base controller.
Related
I use ActiveDataProvider to display some data using GridView. Also I have some data retrieved from API and this is a array. For example:
$emails = [
'123' => 'john#test.io',
'234' => 'jane#test.io',
'345' => 'jake#test.io'
];
$query = new Query();
$query->select(['id', 'username'])->from('user');
$provider = new \yii\data\ActiveDataProvider([
'query' => $query,
'pagination' => [
'pageSize' => 100,
],
]);
Result of displaying this ActiveDataProvider will be something like this:
+------+--------------+
| id | username |
+------+--------------+
| 123 | John |
| 234 | Jane |
| 345 | Jake |
+------+--------------+
How can I join data from query and array to get something like this:
+------+--------------+-------------------+
| id | username | email |
+------+--------------+-------------------+
| 123 | John | john#test.io |
| 234 | Jane | jane#test.io |
| 345 | Jake | jake#test.io |
+------+--------------+-------------------+
I found the only one option - create an array from query and merge it with existing array, but it looks bad for me. Is there any other solution?
You are probably looking for this
https://www.yiiframework.com/doc/api/2.0/yii-data-arraydataprovider
An ArrayDataProvider acts in a lot of the ways the same as an ActiveDataProvider and you can use it as the base data for most of the Yii2 controls. I would get the ActiveDataProvider data, parse it, match it to what you already have by default and create an array that can be used as the base of the ArrayDataProvider.
If you are putting it into a DataGrid you can always do something like this for the email column
[
'class' => 'yii\grid\DataColumn',
'attribute' => 'email',
'format'=>'raw',
'value'=>function ($model) use ($emails) {
return $emails[$model->id];
},
],
A way , for complex or aggregated model, could be based on adding and afterFind method in your model
add the property you need and populate you value with a proper function eg:named getYourRelatedEmail()
or you could use an assigment depending the way you obatin the email array or the related values)
In your model
public $userEmail;
public function afterFind()
{
$this->userEmail = getYourRelatedEmail();
}
in this way you can acces in gridview to the model data field as common model field
In this way you could retrive all the data you need form different sources and build yuor composite model as you need ..
Mutators and Attribute Casting
I have a model with a 'modify' attribute.
The model uses a set attribute. This is because the storage is held as boolean, but the attribute is managed via a select (because the FE options available are three-state: [none | modify | access ] where 'none' is not stored BE.
Storage is as follows (mysql):
+-------------+------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------------+------------------+------+-----+---------+-------+
| prop_id | int(10) unsigned | NO | PRI | NULL | |
| modify | tinyint(1) | NO | | 1 | |
+-------------+------------------+------+-----+---------+-------+
The model uses the following mutator method to translate 'modify' to true.
public function setModifyAttribute($value)
{
$this->attributes['modify'] = ($value === "modify");
}
A typical collection being passed over for sync() is as follows:
$properties =
Collection {
#items: array [
1 => array [
"modify" => "modify"
]
7 => array [
"modify" => "access"
]
]
}
I am then calling sync for the properties as follows:
$this->properties()->sync($properties);
However, the setModifyAttribute() is not being accessed from sync().
Alternatively, using values 'true' and 'false' sync() appears to be ignoring the Attribute Casting hints.
protected $casts = ['modify' => 'boolean'];
Should I run some sort of closure over the collection instead? I would prefer to use a model-centric process.
from the laravel documentation the method setXXXAttribute is just like this
public function setFirstNameAttribute($value)
{
$this->attributes['first_name'] = strtolower($value);
}
so i guess your code should be modified :
public function setModifyAttribute($value){
($value==="Modify"):$this->attributes['modify']=1?$this->attributes['modify']=0;
}
maybe it is wrong ,good luck
Currently, moodle support 4 mnet services
1. Remote enrolment service
2. Portfolio services
3. SSO (Identity Provider)
4. SSO (Service Provider)
to add more mnet service, I need to manually add code for admin/mnet/service.php and then add new in mnet/service (like existing service mnetservice_enrol).
I intent to add new service for retrive course detail information from mnet peer. get_remote_courses method is return course overview only not course detail.
I can not find any document about this is moodle offical site. Is there any toturial about this? or some advise from expert?
Just want to post here method to get course content using webservice rather than using mnet. Moodle support core_course_get_contents in webservice to get course content.
require_once('../../config.php');
$token = '5733b5401924f1e6dafefd326cafeaca';
$domainname = 'http://192.168.1.252';
$courseid = optional_param('remoteid', 0, PARAM_INT);
require_once($CFG->dirroot . '/lib/zend/Zend/Http/Client.php');
$functionname = 'core_course_get_contents';
$serverurl = $domainname . '/webservice/rest/server.php'. '?wstoken=' . $token . '&wsfunction='.$functionname.'&moodlewsrestformat=json';
$client = new Zend_Http_Client($serverurl);
$client->setParameterPost('courseid', $courseid);
$response = $client->request(Zend_Http_Client::POST);
echo $response;
We can add more mnet service by adding mnet.php in yourplugin/db with format:
$publishes = array(
'mnet_enrol' => array(
'apiversion' => 1,
'classname' => 'enrol_mnet_mnetservice_enrol',
'filename' => 'enrol.php',
'methods' => array(
'available_courses',
'user_enrolments',
'enrol_user',
'unenrol_user',
'course_enrolments',
'category_enrolments'
),
),
);
$subscribes = array(
'mnet_enrol' => array(
'available_courses' => 'enrol/mnet/enrol.php/available_courses',
'user_enrolments' => 'enrol/mnet/enrol.php/user_enrolments',
'enrol_user' => 'enrol/mnet/enrol.php/enrol_user',
'unenrol_user' => 'enrol/mnet/enrol.php/unenrol_user',
'course_enrolments' => 'enrol/mnet/enrol.php/course_enrolments',
'category_enrolments'=>'enrol/mnet/enrol.php/category_enrolments'
),
);
New mnet service function is store in mnet_remote_rpc table:
+---------------------+----------------------------------------------+
| functionname | xmlrpcpath |
+---------------------+----------------------------------------------+
| user_authorise | auth/mnet/auth.php/user_authorise |
| keepalive_server | auth/mnet/auth.php/keepalive_server |
| kill_children | auth/mnet/auth.php/kill_children |
| refresh_log | auth/mnet/auth.php/refresh_log |
| fetch_user_image | auth/mnet/auth.php/fetch_user_image |
| fetch_theme_info | auth/mnet/auth.php/fetch_theme_info |
| update_enrolments | auth/mnet/auth.php/update_enrolments |
| keepalive_client | auth/mnet/auth.php/keepalive_client |
| kill_child | auth/mnet/auth.php/kill_child |
| available_courses | enrol/mnet/enrol.php/available_courses |
| user_enrolments | enrol/mnet/enrol.php/user_enrolments |
| enrol_user | enrol/mnet/enrol.php/enrol_user |
| unenrol_user | enrol/mnet/enrol.php/unenrol_user |
| course_enrolments | enrol/mnet/enrol.php/course_enrolments |
| send_content_intent | portfolio/mahara/lib.php/send_content_intent |
| send_content_ready | portfolio/mahara/lib.php/send_content_ready |
| category_enrolments | enrol/mnet/enrol.php/category_enrolments |
+---------------------+----------------------------------------------+
it the same with adding new web service. To update new service you need to increase version in version.php.
I am creating migrations in codeigniter. But I get an error saying that migrations are not found. I consulted official codeigniter docs. But in google, I couldn't find this error.
I created migrations folder and added following file.
001_Create_users.php
<? php
/**
* Description of 001_create_users
*
* #author Isuru
*/
class Migration_Create_users extends CI_Migration {
public
function up() {
$this - > dbforge - > add_field('id');
$this - > dbforge - > add_field(array(
'id' => array(
'type' => 'INT',
'constraint' => 11,
'unsigned' => TRUE,
'auto_increment' => TRUE
),
'email' => array(
'type' => 'VARCHAR',
'constraint' => '100',
),
'password' => array(
'type' => 'VARCHAR',
'constraint' => '100',
),
'name' => array(
'type' => 'VARCHAR',
'constraint' => '100',
),
));
//$this->dbforge->add_key('id', TRUE);
$this - > dbforge - > create_table('users');
}
public function down() {
$this - > dbforge - > drop_table('users');
}
}
This is the migration.php
<?php
defined('BASEPATH') OR exit('No direct script access allowed');
/*
|--------------------------------------------------------------------------
| Enable/Disable Migrations
|--------------------------------------------------------------------------
|
| Migrations are disabled by default for security reasons.
| You should enable migrations whenever you intend to do a schema migration
| and disable it back when you're done.
|
*/
$config['migration_enabled'] = TRUE;
/*
|--------------------------------------------------------------------------
| Migration Type
|--------------------------------------------------------------------------
|
| Migration file names may be based on a sequential identifier or on
| a timestamp. Options are:
|
| 'sequential' = Default migration naming (001_add_blog.php)
| 'timestamp' = Timestamp migration naming (20121031104401_add_blog.php)
| Use timestamp format YYYYMMDDHHIISS.
|
| If this configuration value is missing the Migration library defaults
| to 'sequential' for backward compatibility.
|
*/
$config['migration_type'] = 'timestamp';
/*
|--------------------------------------------------------------------------
| Migrations table
|--------------------------------------------------------------------------
|
| This is the name of the table that will store the current migrations state.
| When migrations runs it will store in a database table which migration
| level the system is at. It then compares the migration level in this
| table to the $config['migration_version'] if they are not the same it
| will migrate up. This must be set.
|
*/
$config['migration_table'] = 'migrations';
/*
|--------------------------------------------------------------------------
| Auto Migrate To Latest
|--------------------------------------------------------------------------
|
| If this is set to TRUE when you load the migrations class and have
| $config['migration_enabled'] set to TRUE the system will auto migrate
| to your latest migration (whatever $config['migration_version'] is
| set to). This way you do not have to call migrations anywhere else
| in your code to have the latest migration.
|
*/
$config['migration_auto_latest'] = TRUE;
/*
|--------------------------------------------------------------------------
| Migrations version
|--------------------------------------------------------------------------
|
| This is used to set migration version that the file system should be on.
| If you run $this->migration->current() this is the version that schema will
| be upgraded / downgraded to.
|
*/
$config['migration_version'] = 1;
/*
|--------------------------------------------------------------------------
| Migrations Path
|--------------------------------------------------------------------------
|
| Path to your migrations folder.
| Typically, it will be within your application path.
| Also, writing permission is required within the migrations path.
|
*/
$config['migration_path'] = APPPATH.'migrations/';
I tried to find a solution since yesterday, but I could not find a solution.
Change 'timestamp' to 'sequential' if you want to use '001'
You have a typo in 001_Create_users.php
<? php
and
- >
For version 3.1.10 the correct path for migrations is /application/migrations.
hth
plese be sure that name of migration folder under applications to be migrations.
Hope it helps!
I've seen through all other questions but I can't figure why My Auth::attempt is not working
Then, I'll display the code involved on it:
-- models/Usuario.php --
use \Illuminate\Auth\UserInterface;
class Usuario extends Eloquent implements UserInterface{
protected $table = 'User_Account';
protected $hidden = array('password');
public function getAuthIdentifier() {
return $this->getKey();
}
public function getAuthPassword() {
return $this->password;
}
}
?>
auth.php
<?php
return array(
/*
|--------------------------------------------------------------------------
| Default Authentication Driver
|--------------------------------------------------------------------------
|
| This option controls the authentication driver that will be utilized.
| This driver manages the retrieval and authentication of the users
| attempting to get access to protected areas of your application.
|
| Supported: "database", "eloquent"
|
*/
'driver' => 'eloquent',
/*
|--------------------------------------------------------------------------
| Authentication Model
|--------------------------------------------------------------------------
|
| When using the "Eloquent" authentication driver, we need to know which
| Eloquent model should be used to retrieve your users. Of course, it
| is often just the "User" model but you may use whatever you like.
|
*/
'model' => 'Usuario',
/*
|--------------------------------------------------------------------------
| Authentication Table
|--------------------------------------------------------------------------
|
| When using the "Database" authentication driver, we need to know which
| table should be used to retrieve your users. We have chosen a basic
| default value but you may easily change it to any table you like.
|
*/
'table' => 'User_Account',
/*
|--------------------------------------------------------------------------
| Password Reminder Settings
|--------------------------------------------------------------------------
|
| Here you may set the settings for password reminders, including a view
| that should be used as your password reminder e-mail. You will also
| be able to set the name of the table that holds the reset tokens.
|
| The "expire" time is the number of minutes that the reminder should be
| considered valid. This security feature keeps tokens short-lived so
| they have less time to be guessed. You may change this as needed.
|
*/
'reminder' => array(
'email' => 'emails.auth.reminder',
'table' => 'password_reminders',
'expire' => 60,
),
);
My Route::post(Controller#method) here:
$validator = $this->getLoginValidator();
if ($validator->passes()) {
if(Auth::attempt(array('username' => Input::get('username'), 'password' => Input::get('password')))){
echo "entrou";
}
echo "n entrou";
} else{
echo "Validation failed!";
}
I've seen what comes from each Input::get and everything seems alright.
Just to information, my tables like this:
Column Type Null Default Comments
id int(8) No
firstname varchar(40) No
lastname varchar(40) No
password varchar(60) No
username varchar(40) No
points int(8) No 0
created_at datetime No
updated_at datetime No
If you need additional information in order to help me, I'd freely give.