I am working on CakePHP 3 project where I have to add social login.
For that I'm using HybridAuth following the tutorial from Here
Now When I access http://website.com/users/social/Facebook I get error as
Hybriauth config does not exist on the given path.
My UsersController is
<?php
namespace App\Controller;
use App\Controller\AppController;
use Cake\Event\Event;
/**
* Users Controller
*
* #property \App\Model\Table\UsersTable $Users
*/
class UsersController extends AppController
{
public function beforeFilter(Event $event)
{
parent::beforeFilter($event);
$this->Auth->allow(['register','logout','social','social_redirect']);
}
public function login()
{
if ($this->request->is('post')) {
$user = $this->Auth->identify();
if ($user) {
$this->Auth->setUser($user);
return $this->redirect($this->Auth->redirectUrl());
}
$this->Flash->error(__('Invalid username or password'));
}
}
public function social($provider)
{
/* Include the config file */
require_once(ROOT . DS . 'vendor' . DS . 'hybridauth' . DS . 'hybridauth' . DS . 'hybridauth' . DS . 'config.php');
require_once(ROOT . DS . 'vendor' . DS . 'hybridauth' . DS . 'hybridauth' . DS . 'hybridauth' . DS . 'Hybrid' . DS . 'Auth.php');
/* Initiate Hybrid_Auth Function */
$hybridauth = new \Hybrid_Auth($config);
$authProvider = $hybridauth->authenticate($provider);
$user_profile = $authProvider->getUserProfile();
/* Modify here as per need. This is for demo */
if ($user_profile && isset($user_profile->identifier)) {
echo "<b>Name</b> : " . $user_profile->displayName . "<br />";
echo "<b>Profile URL : </b>" . $user_profile->profileURL . "<br />";
echo "<b>Image : </b>" . $user_profile->photoURL . "<br />";
echo "<img src='" . $user_profile->photoURL . "'<br />";
echo "<b>Email : </b>" . $user_profile->email . "<br />";
echo "<br /> <a href='logout.php'>Logout</a>";
}
exit;
/* Example demo for FB authorize Action */
#Facebook authorize
if ($this->request->params['pass'][0] == 'Facebook') {
if ($user_profile && isset($user_profile->identifier)) {
$this->authorize_facebook($user_profile);
}
}
}
public function social_redirect()
{
$this->layout = false;
$this->autoRender = false;
require_once(ROOT . DS . 'vendor' . DS . 'hybridauth' . DS . 'hybridauth' . DS . 'hybridauth' . DS . 'config.php');
require_once(ROOT . DS . 'vendor' . DS . 'hybridauth' . DS . 'hybridauth' . DS . 'hybridauth' . DS . 'Hybrid' . DS . 'Auth.php');
require_once(ROOT . DS . 'vendor' . DS . 'hybridauth' . DS . 'hybridauth' . DS . 'hybridauth' . DS . 'Hybrid' . DS . 'Endpoint.php');
$hybridauth = new \Hybrid_Auth($config);
\Hybrid_Endpoint::process();
}
public function authorize_facebook($user_profile)
{
$provider = 'Facebook';
$provider_uid = $user_profile->identifier;
$userExist = $this->Users->find('all')->where(['Users.provider' => $provider, 'Users.provider_uid' => $user_profile->identifier])->first();
if ((isset($userExist)) && ($userExist)) {
$session = $this->request->session();
$session->delete('auth_sess_var');
$session->destroy();
$this->Auth->setUser($userExist->toArray());
$session->write('auth_sess_var', $userExist);
return $this->redirect($this->Auth->redirectUrl());
} else {
/* Create new user entity */
$user = $this->Users->newEntity();
$tmp_hash = md5(rand(0, 1000));
$tmp_id = time();
/* Save individual data */
$user->tmp_id = $tmp_id;
$firstName = (!empty($user_profile->firstName)) ? $user_profile->firstName : "";
$lastName = (!empty($user_profile->lastName)) ? $user_profile->lastName : "";
$user->name = $firstName . ' ' . $lastName;
// $user->username = (!empty($user_profile->firstName) && !empty($user_profile->lastName)) ? strlolower($user_profile->firstName) . "." . strtolower($user_profile->lastName) : "";
// $user->avatar = (!empty($user_profile->photoURL)) ? $user_profile->photoURL : "";
// $user->role = "public";
$user->provider = $provider;
$user->provider_uid = $user_profile->identifier;
$user->email = !empty($user_profile->email) ? $user_profile->email : "";
$user->password = $user_profile->identifier;
// $user->confirm_password = $user_profile->identifier;
$user->tmp_hash = $tmp_hash;
$user->verified = (!empty($user_profile->emailVerified)) ? 1 : 0;
$user = $this->Users->patchEntity($user, $this->request->data);
$this->Users->save($user);
$userDetails = $this->Users->find('all')
->where(['Users.provider' => $provider, 'Users.provider_uid' => $user_profile->identifier])->first();
/* Destroy previous session before setting new Session */
$session = $this->request->session();
$session->delete('auth_sess_var');
$session->destroy();
/* Set user */
$this->Auth->setUser($userDetails->toArray());
$session->write('auth_sess_var', $userDetails);
return $this->redirect($this->Auth->redirectUrl());
}
}
public function logout()
{
return $this->redirect($this->Auth->logout());
}
}
I have installed HybridAuth : version 2.5.1 using composer and its location is
| / root
|- vendor
|- hybridauth
|- hybridauth
|- hybridauth
|- Hybrid (directory)
|- Auth.php
|- ...
|- config.php
|- index.php
content of config.php
<?php
/**
* HybridAuth
* http://hybridauth.sourceforge.net | http://github.com/hybridauth/hybridauth
* (c) 2009-2015, HybridAuth authors | http://hybridauth.sourceforge.net/licenses.html
*/
// ----------------------------------------------------------------------------------------
// HybridAuth Config file: http://hybridauth.sourceforge.net/userguide/Configuration.html
// ----------------------------------------------------------------------------------------
return
array(
"base_url" => "http://website.com/users/social-redirect/",
"providers" => array(
// openid providers
"OpenID" => array(
"enabled" => true
),
"Yahoo" => array(
"enabled" => true,
"keys" => array("key" => "", "secret" => ""),
),
"AOL" => array(
"enabled" => true
),
"Google" => array(
"enabled" => true,
"keys" => array("id" => "", "secret" => ""),
),
"Facebook" => array(
"enabled" => true,
"keys" => array("id" => "id", "secret" => "key"),
"trustForwarded" => false
),
"Twitter" => array(
"enabled" => true,
"keys" => array("key" => "", "secret" => ""),
"includeEmail" => false
),
// windows live
"Live" => array(
"enabled" => true,
"keys" => array("id" => "", "secret" => "")
),
"LinkedIn" => array(
"enabled" => true,
"keys" => array("key" => "", "secret" => "")
),
"Foursquare" => array(
"enabled" => true,
"keys" => array("id" => "", "secret" => "")
),
),
// If you want to enable logging, set 'debug_mode' to true.
// You can also set it to
// - "error" To log only error messages. Useful in production
// - "info" To log info and error messages (ignore debug messages)
"debug_mode" => false,
// Path to file writable by the web server. Required if 'debug_mode' is not false
"debug_file" => "",
);
What is wrong with the code ?
this is the way to remove error:
in users controller where you call(require) config.php
require_once(ROOT . DS . 'vendor' . DS . 'hybridauth' . DS . 'hybridauth' . DS . 'hybridauth' . DS . 'config.php');
you need to store that what you require in variable $config:
$config = require_once(ROOT . DS . 'vendor' . DS . 'hybridauth' . DS . 'hybridauth' . DS . 'hybridauth' . DS . 'config.php');
best regards
Related
I would like to know how I can improve this CakePHP 3.0 Component (inside folder controller)
1st: to use external libs (stored on vendor folder) I'm using the require keyword and include the class using use keyword, like this:
require_once(ROOT . DS . 'vendor' . DS . 'CakePHP-ImageTool-Component' . DS . 'ImageTool.php');
and
use ImageTool;
How I can put this on CakePHP 3 pattern ?
2nd: in method saveFileLFS I'm using true or false to flag OK.
How I can improve this check ?
<?php
namespace App\Controller\Component;
require_once(ROOT . DS . 'vendor' . DS . 'CakePHP-ImageTool-Component' . DS . 'ImageTool.php');
use Burzum\FileStorage\Lib\StorageManager;
use Cake\Controller\Component;
use ImageTool;
class UploadFileComponent extends Component
{
function resizeImage($settings)
{
$status = ImageTool::resize([
'input' => $settings['input'],
'output' => $settings['output'],
'width' => $settings['width'],
'height' => $settings['height'],
'mode' => $settings['mode']
]);
return $status;
}
public function saveFileLFS($stringSeparator, $storeName, $productName)
{
$key = $storeName . $stringSeparator . $productName . $stringSeparator .
$this->request->data['Media']['file']['name'];
if(StorageManager::adapter('Local')->write($key,
file_get_contents($this->request->data['Media']['file']['tmp_name']))){
return true;
}else
{
return false;
}
}
}
I have a action to save data in 4 models. Here is my controller code. I do get any error for saving data, I double checked it, But this action does not redirect to given url after it saves data, all it shows is a blank page of same action (action which is used to save data). This problem is only on live server. In my local copy is just working fine.
if ($this->request->is('post')) {
//First upload user pic
if ($this->request->data['FacilityResident']['pic']['name'] != NULL) {
$pic = $this->request->data['FacilityResident']['pic']['tmp_name'];
if (!is_dir(WWW_ROOT . 'img' . DS . 'residents' . DS)) {
mkdir(WWW_ROOT . 'img' . DS . 'residents' . DS);
chmod(WWW_ROOT . 'img' . DS . 'residents' . DS, 0777);
}
$uniq = mt_rand();
move_uploaded_file($pic, WWW_ROOT . 'img' . DS . 'residents' . DS . $this->request->data['FacilityResident']['pic']['name']);
$this->request->data['FacilityResident']['avatar'] = DS . 'residents' . DS . $this->request->data['FacilityResident']['pic']['name'];
unset($this->request->data['FacilityResident']['pic']);
}
$this->request->data['FacilityResident']['facilities_id'] = $this->Session->read('urlparam.facilityId');
$this->FacilityResident->save($this->request->data['FacilityResident']);
$residentId = $this->FacilityResident->getLastInsertID();
if (!empty($this->request->data['FacilityResidentDietary']['diet'])) {
$dietData = implode(',', $this->request->data['FacilityResidentDietary']['diet']);
unset($this->request->data['FacilityResidentDietary']['diet']);
$this->request->data['FacilityResidentDietary']['diet'] = $dietData;
}
$this->request->data['FacilityResidentDietary']['facility_residents_id'] = $residentId;
$this->FacilityResidentDietary->save($this->request->data['FacilityResidentDietary']);
$this->request->data['ResidentMealschedule']['facility_residents_id'] = $residentId;
$this->ResidentMealschedule->save($this->request->data['ResidentMealschedule']);
$residentMealSchedultId = $this->ResidentMealschedule->getLastInsertID();
foreach ($this->request->data['Mealdetail'] as $key => $value) {
if ($key == 'Bread') {
$value[0]['attribute_four'] = implode(',', array_filter($value[0]['attribute_four']));
}
foreach ($value as $val) {
$this->Mealdetail->saveAll($val);
$data['Mealschedule']['meal_types_id'] = 1;
$data['Mealschedule']['resident_mealschedule_id'] = $residentMealSchedultId;
$data['Mealschedule']['mealdetails_id'] = $this->Mealdetail->getLastInsertID();
$this->Mealschedule->saveAll($data);
}
unset($data);
unset($val);
}
$i = 1;
foreach ($this->request->data['ResidentMealMeta'] as $key => $val) {
$data['ResidentMealMeta'][$i]['resident_mealschedule_id'] = $residentMealSchedultId;
$data['ResidentMealMeta'][$i]['meal_value'] = $key;
$data['ResidentMealMeta'][$i]['meal_option'] = $val;
$i++;
}
if (!empty($this->request->data['ResidentTray']['tray'][0])) {
$j = count($data['ResidentMealMeta']) + 1;
$data['ResidentMealMeta'][$j]['meal_value'] = 'tray';
$data['ResidentMealMeta'][$j]['resident_mealschedule_id'] = $residentMealSchedultId;
$data['ResidentMealMeta'][$j]['meal_option'] = implode(',', $this->request->data['ResidentTray']['tray']);
}
unset($this->request->data['ResidentMealMeta']);
unset($this->request->data['ResidentTray']);
if ($this->ResidentMealMeta->saveAll($data['ResidentMealMeta'])) {
$this->Session->setFlash('New resident added', 'flash', array('alert' => 'success'));
if(isset($url)){
unset($url);
}
$url = Router::url(array(
'controller' => 'residents',
'action' => 'resident_list',
'?' => array('facility_name' => $this->Session->read('urlparam.facilityName'), 'facility_id' => $this->Session->read('urlparam.facilityId'))
));
$this->redirect($url);
}
}
can any one here tell me what is going wrong? I have also tried saving data via related model, but no effect.
I suggest to use this solution :
Router::redirect(
'/controller_where_you_re_saving_data/*',
array('controller' => 'residents', 'action' => 'resident_list'),
// view action expects $id as an argument
array('facility_name' => $this->Session->read('url.facilityName'))
);
However , i suggest to not pass the argument when it 's about sessions values , cause you can access to it in every controller in you project , which make the solution like this :
Router::redirect(
'/controller_where_you_re_saving_data/*',
array('controller' => 'residents', 'action' => 'resident_list'),
);
Here is the document :
http://book.cakephp.org/2.0/en/development/routing.html#redirect-routing
Hope it helps.
i am working on a cakephp 2.x ... i have a form in which i am taking the file from the user and then i am saving fileinto the app/uploads/userid folder and saving the path into db ... i am successfully fetch the file and showing it to the user but now the problem is during downloading.. i mean whenever user click the file link it will redirected the user to some unknown link
here is my code
public function uploadFile(){
if ($this->request->isPost()){
$this->loadModel('Audio');
$file = $this->request->data['Audio']['file'];
$idUser = $this->Auth->user('idUser');
if ($file['error'] === UPLOAD_ERR_OK) {
$id = String::uuid();
$name =$file['name'];
$folder_url = APP.'uploads/'.$idUser;
if(!is_dir($folder_url)) {
mkdir($folder_url);
}
move_uploaded_file($file['tmp_name'], $folder_url.DS.$name);
$this->request->data['Audio']['User_id'] = $idUser;
$this->request->data['Audio']['filename'] = $file['name'];
$this->request->data['Audio']['filesize'] = $file['size'];
$this->request->data['Audio']['filemime'] = $file['type'];
$this->Audio->save($this->request->data);
return true;
}
}
return false;
}
public function showfile(){
$this->loadModel('Audio');
$record = $this->Audio->find('first', array('conditions' => array('User_id' => $this->Auth->user('idUser'))));
$this->set('file', $record);
}
on my view page
<?php echo $this->Html->link($file['Audio']['filename'], APP . DS . 'uploads' . DS . $file['Audio']['User_id'] . DS . $file['Audio']['filename'] . DS . $file['Audio']['filemime']);?>
here is the url after clicking the link
/localhost/cakephp/media/C:/xampp/htdocs/cakephp/app//uploads/23/1011029_10152615392142588_1926259269_n.jpg/image/jpeg
i have tried every thing to make it work both nothing works out for me .. please i need help ..
you can add like this with name of filename to click
<?php echo $this->Html->link($file['Audio']['filename'], 'uploads' . DS . $file['Audio']['User_id'] . DS . $file['Audio']['filename'] . DS . $file['Audio']['filemime'], array('target' => '_blank')); ?>
for more understanding just go throw this cakephp.org link to understand html helper functionality
i hope it will useful to you.
i am working on a Cakephp 2.x .. what i have done right now is .. i am displaying a user a form in which i have given him the option to upload an audio file .. so i have taken the file from the user .. i am saving the file into the app/uploads folder .. and the path into the database ... now the problem is i dont how can i know retrieve my audio file and show them into my view page
here is my uploading function
public function audio(){
if ($this->request->isPost()){
$this->loadModel('Audio');
$file = $this->request->data['Audio']['file'];
$idUser = $this->Auth->user('idUser');
if ($file['error'] === UPLOAD_ERR_OK) {
$id = String::uuid();
$name =$file['name'];
$folder_url = APP.'uploads/'.$idUser;
if(!is_dir($folder_url)) {
mkdir($folder_url);
}
move_uploaded_file($file['tmp_name'], $folder_url.DS.$name);
$this->request->data['Audio']['User_id'] = $idUser;
$this->request->data['Audio']['filename'] = $file['name'];
$this->request->data['Audio']['filesize'] = $file['size'];
$this->request->data['Audio']['filemime'] = $file['type'];
$this->Audio->save($this->request->data);
return true;
}
}
return false;
}
public function showAllAudioFiles(){
}
now the file of particular user has stored into this folder app/uploads/23/file.mp3
Answer:
Assuming you only have one file per user, you jsut need to find the database record and construct the path from that:
public function showAllAudioFiles(){
$record = $this->Audio->find('first', array('conditions' => array('User_id' => $this->Auth->user('idUser')));
$file = APP . 'uploads' . DS . $this->Auth->user('idUser') . DS . $record['Audio']['filename'] . '.' . $record['Audio']['filemime'];
$this->set('file', $file);
}
If a user can have multiple files:
public function showAllAudioFiles(){
$records = $this->Audio->find('all', array('conditions' => array('User_id' => $this->Auth->user('idUser')));
$files = array();
foreach ($records as $record) {
$files[] = APP . 'uploads' . DS . $this->Auth->user('idUser') . DS . $record['Audio']['filename'] . '.' . $record['Audio']['filemime'];
}
$this->set('files', $files);
}
Now the $file variable will contain a string of the format app/uploads/23/file.mp3, for example. Or $files will be an array of those strings.
Suggestion:
Doing it the proper 'Cake' way, you would just retrieve the records and echo them using the media method of HtmlHelper:
ACTION:
public function showAllAudioFiles(){
$record = $this->Audio->find('first', array('conditions' => array('User_id' => $this->Auth->user('idUser')));
$this->set('file', $record);
}
VIEW:
echo $this->Html->media($file['Audio']['filename'] . '.' . $file['Audio']['filemime'],
array('pathPrefix' => 'uploads' . DS . $file['Audio']['User_id']
);
This should output something like this:
<audio src="/uploads/23/file.mp3"></audio>
Creating a link to the file
Edit: For links to files, just use HtmlHelper's link method:
echo $this->Html->link($file['Audio']['filename'], WWW_ROOT . DS . 'uploads' . DS . $file['Audio']['User_id'] . DS . $file['Audio']['filename'] . DS . $file['Audio']['filemime']);
HtmlHelper::media
I am trying to load a separate mobile view and having a problem.
I can get my mobile layout to work but not the view.
I was using this question as a reference and I am running cakephp 2.1
CakePHP website mobile version
I am not sure how to structure my mobile views?
Is it /app/View/name/mobile/view.ctp or
/app/View/mobile/name/view.ctp or something else. I have been going in circles trying to figure this out. Any suggestions.
My AppController.php
Before Filter
public function beforeFilter() {
/* mobile layout testing */
if ($this->request->isMobile()){
$this->is_mobile = true;
$this->set('is_mobile', true );
$this->autoRender = false;
} else {
$this->set('is_mobile', false );
}
}
After Filter (shortened)
function afterFilter() {
$view_file = file_exists(
"/var/www" .
$this->webroot .
"app" . DS .
'View' . DS .
$this->name . DS .
'mobile/' .
$this->action .
'.ctp'
);
$layout_file = file_exists(
"/var/www" .
$this->webroot .
"app" . DS .
'View' . DS .
'Layouts' . DS .
'mobile/' .
$this->layout .
'.ctp'
);
if($view_file || $layout_file){
$this->render(
$this->action,
($layout_file?'mobile/':'').$this->layout,
($view_file?'mobile/':'').$this->action
);
}
}
In previous version(s) of CakePHP, $this->render() had three parameters, but in 2.x and beyond, it only has 2:
CakePHP 1.3 API for Controller render() - has 3 parameters:
http://api13.cakephp.org/class/controller#method-Controllerrender
CakePHP 2.0 API for Controller render() - has only 2 parameters:
http://api20.cakephp.org/class/controller#method-Controllerrender
Becuase of that, your answer utilizing only 2 parameters works much better than your attempt with 3. :)
(The CakePHP Book still incorrectly states that there are 3 parameters, so - I certainly don't blame you for trying as it's mentioned - had to look it up in more detail to find this out)
I ended up doing this below. My view folders now check for a mobile folder and load the view if it exists.
function afterFilter() {
// if in mobile mode, check for a valid view and use it
if (isset($this->is_mobile) && $this->is_mobile) {
$has_mobile_view_file = file_exists( ROOT . DS . APP_DIR . DS . 'View' . DS . $this->name . DS . 'mobile' . DS . $this->action . '.ctp' );
$has_mobile_layout_file = file_exists( ROOT . DS . APP_DIR . DS . 'View' . DS . 'Layouts' . DS . 'mobile' . DS . $this->layout . '.ctp' );
$view_file = ( $has_mobile_view_file ? 'mobile' . DS : '' ) . $this->action;
$layout_file = ( $has_mobile_layout_file ? 'mobile' . DS : '' ) . $this->layout;
$this->render( $view_file, $layout_file );
}
}