How to use socialize(facebook) with laravel 5.1 - facebook

I followed this guide
Laravel\Socialite\SocialiteServiceProvider in my config/app.php is ok, and aliases should also be ok : 'Socialite' => Laravel\Socialite\Facades\Socialite::class,
Here is my code :
config/services.php
'facebook' => [
'client_id' => 'xxxx',
'client_secret' => 'xxxxx',
'redirect' => 'http://localhost:8000/auth/fb',
]
Route
Route::get('auth/fb', 'FBController#redirectToProvider');
Route::get('auth/fb/callback', 'FBController#handleProviderCallback');
Controller
namespace App\Http\Controllers;
use Socialite;
use Illuminate\Routing\Controller;
class FBController extends Controller`
{
public function redirectToProvider()
{
return Socialite::driver('facebook')->redirect();
}
public function handleProviderCallback()
{
$user = Socialite::driver('facebook')->user();
}
}
but is error in
FatalErrorException in FBController.php line 14:
Class 'App\Http\Controllers\Socialite' not found
What can I do to fix this?

Replace use Socialite; with use Socialize; and all instances where Socialite replace it with Socialize
namespace App\Http\Controllers;
use Socialize;
use Illuminate\Routing\Controller;
class FBController extends Controller
{
public function redirectToProvider()
{
return Socialize::driver('facebook')->redirect();
}
public function handleProviderCallback()
{
$user = Socialize::driver('facebook')->user();
}
}

Related

Yii2: rest api model get data

I am using REST API in my project and everything works great. I describe a model using a model
<?php
namespace api\modules\v1\models;
use Carbon\Carbon;
use Yii;
class Comment extends \common\models\Comment
{
public function fields()
{
return [
'id',
'user' => function(Comment $model) {
return User::findOne($model->user_id);
},
'text',
'image' => function(Comment $model) {
return Yii::$app->params['link'].$model->image;
},
'created_at' => function(Comment $model) {
Carbon::setLocale(Yii::$app->language);
return Carbon::createFromTimeStamp(strtotime($model->created_at))->diffForHumans();
},
'children' => function(Comment $model) {
$comments = Comment::find()
->where(['comment_id' => $model->id]);
if (!$comments->exists()) {
return false;
}
return $comments->all();
},
'like',
'news_id',
'comment_id'
];
}
}
The data is returned in the specified format and that's great. But I need to send data to the controller using websockets. For example, when a new comment arrives, send it to all users.
$post = Yii::$app->request->post();
$image = UploadedFile::getInstanceByName('image');
$model = new \api\modules\v1\models\Comment([
'news_id' => $post['feed_id'],
'comment_id' => $post['comment_id'] ?? null,
'user_id' => Yii::$app->user->identity->id,
]);
$model->text = $model->findLinks($post['text']);
if ($image && !$image->error) {
if (!file_exists(Yii::$app->params['comment.pathAbsolute'])) {
if (!FileHelper::createDirectory(Yii::$app->params['comment.pathAbsolute'], 0777)) {
throw new \Exception('Помилка створення папки');
}
}
$serverName = Yii::$app->security->generateRandomString(16).'.'.$image->extension;
if ($image->saveAs(Yii::$app->params['comment.pathAbsolute'].$serverName)) {
$model->image = $serverName;
} else {
throw new \Exception($image->error);
}
}
if (!$model->save()) {
throw new \Exception($model->error());
}
Helper::ws(false, 'updateComment', ['feed_id' => $post['feed_id'], 'comment' => $model]);
And when I pass the $model, the data is passed as it is stored in the database. Is it possible to call a method or something so that the data is passed as I described in the model api?

MassTransit help registering multiple sagas

I'm working on porting an old app to .net6, and ran into an issue with registrering multiple sagas with masstransit.
services.AddMassTransit<IProcessManagerBus>(busCfg =>
{
busCfg.AddSagaStateMachine<OrderPM, OrderPMState>()
.EntityFrameworkRepository<OrderPMState>(efConfig =>
{
efConfig.ConcurrencyMode = ConcurrencyMode.Optimistic;
efConfig.DatabaseFactory(() => new OrderStateDbContext(configuration.GetConnectionString("DB")));
});
busCfg.AddSagaStateMachine<CsaLoginPM, CsaLoginPMState>()
.EntityFrameworkRepository<CsaLoginPMState>(efConfig =>
{
efConfig.ConcurrencyMode = ConcurrencyMode.Optimistic;
efConfig.DatabaseFactory(() => new CsaLoginStateDbContext(configuration.GetConnectionString("DB")));
});
busCfg.UsingRabbitMq((context, rabbitCfg) =>
{
rabbitCfg.UseJsonSerializer();
rabbitCfg.Host(new Uri(configuration.GetValue<string>("messaging:pm-bus:host-address")), hostCfg =>
{
hostCfg.Username(configuration.GetValue<string>("messaging:pm-bus:username"));
hostCfg.Password(configuration.GetValue<string>("messaging:pm-bus:password"));
rabbitCfg.ReceiveEndpoint(configuration.GetValue<string>("messaging:pm-bus:receive-queue"), epCfg =>
{
epCfg.PrefetchCount = 10;
epCfg.UseRetry(retryConfig => retryConfig.Exponential(5, TimeSpan.FromMilliseconds(500), TimeSpan.FromMinutes(1), TimeSpan.FromSeconds(1)));
epCfg.ConfigureSagas(context);
});
});
});
});
The OrderPMState works fine, but the CsaLoginPMState gives the following error when triggered: System.InvalidOperationException: The entity type CsaLoginPMState is not part of the model for the current context.
If I comment out the registration of the OrderPMState, the CsaLoginPMState works fine. I suspect, that the 2 sagas are using the same DbContext, despite being registered with their individual DbContext.
OrderStateDbContext
public class OrderStateDbContext : SagaDbContext
{
public OrderStateDbContext(string nameOrConnectionString)
: base(nameOrConnectionString)
{
}
protected override IEnumerable<ISagaClassMap> Configurations
{
get { yield return new OrderPMStateMapping(); }
}
}
CsaLoginStateDbContext
public class CsaLoginStateDbContext : SagaDbContext
{
public CsaLoginStateDbContext(string nameOrConnectionString)
: base(nameOrConnectionString)
{
}
protected override IEnumerable<ISagaClassMap> Configurations
{
get { yield return new CsaLoginPMStateMapping(); }
}
}
The old version of the app used AutoFac, and the registration was done like this:
builder.Register(x =>
EntityFrameworkSagaRepository<OrderPMState>.CreateOptimistic(() => new OrderStateDbContext(_configuration.GetConnectionString("DB"))))
.As<ISagaRepository<OrderPMState>>().SingleInstance();
builder.Register(x =>
EntityFrameworkSagaRepository<CsaLoginPMState>.CreateOptimistic(() => new CsaLoginStateDbContext(_configuration.GetConnectionString("DB"))))
.As<ISagaRepository<CsaLoginPMState>>().SingleInstance();
Am I missing something?
When using a DbContext, you should be using one of the two configuration methods that are specifically designed for use with DbContext.
busCfg.AddSagaStateMachine<CsaLoginPM, CsaLoginPMState>()
.EntityFrameworkRepository<CsaLoginPMState>(efConfig =>
{
efConfig.ConcurrencyMode = ConcurrencyMode.Optimistic;
efConfig.AddDbContext<DbContext, CsaLoginStateDbContext>((provider,builder) =>
{
builder.UseSqlServer(configuration.GetConnectionString("DB"), m =>
{
m.MigrationsAssembly(Assembly.GetExecutingAssembly().GetName().Name);
m.MigrationsHistoryTable($"__{nameof(CsaLoginStateDbContext)}");
});
});
});
Or you can add the DbContext separately and use that existing DbContext in the saga:
services.AddDbContext<CsaLoginStateDbContext>(builder =>
builder.UseSqlServer(configuration.GetConnectionString("DB"), m =>
{
m.MigrationsAssembly(Assembly.GetExecutingAssembly().GetName().Name);
m.MigrationsHistoryTable($"__{nameof(CsaLoginStateDbContext)}");
}));
services.AddMassTransit(x =>
{
x.AddSagaRepository<JobSaga>()
.EntityFrameworkRepository(r =>
{
r.ConcurrencyMode = ConcurrencyMode.Optimistic;
r.ExistingDbContext<CsaLoginStateDbContext>();
});
});
This is all covered in the documentation.

Octobercms, redirect to home from component not working

i'm trying to redirect from component if id from slug is wrong.
Running from layout
function onBeforePageStart(){ $this->Contentloader->getMeta(); }
In component i have:
public function getMeta(){
//id checking logic goes here
if ($id == null) return Redirect::to('/'); }
Inspecting the dd(Redirect::to('/')) object I see
But it's not redirecting.
Please advice
Thanks
try this
in your component :
public function getMeta()
{
if ($id == null) return false;
}
in your layout :
function onBeforePageStart()
{
$meta = $this->Contentloader->getMeta();
if(!$meta)
return Redirect::to('/');
}
I hope help you :)
Components should be able to handle redirects without having onBeforePageStart(). This is just a quick example. Here I am checking to see if a component field is null. If it is null then return to '/'.
You can do this in a component: Make sure to utilize the Redirect class use Redirect;
public function defineProperties()
{
return [
'useSomething' => [
'title' => 'Something',
'description' => 'Testing Testing',
'default' => '',
'type' => 'text',
]
];
}
public function onRun()
{
if ($this->property('useSomething') == null) {
return Redirect::to('/');
} else {
$this->page['something'] = $this->property('useSomething');
}
}

Using Scopes on the Load method not working

Is there a way to abstract this Closure to my MerchantUser model in a way similar to using scopes on with()?
So far I have this which works:
$merchant_user->load(['permissions' => function ($query) use ($merchantId) {
if ($merchantId) {
$query->where('merchant_user_permission.merchant_id','=', $merchantId);
}
}]);
But I'd like to do something like this:
$merchant_user->loadPermissions($merchantId);
In my Model:
public function scopeLoadPermissions($query, $merchantId = null)
{
return $query->load(['permissions' => function ($q) use ($merchantId) {
if ($merchantId) {
$q->where('merchant_user_permission.merchant_id','=', $merchantId);
}
}]);
}
Which at the moment just returns an error:
"Method Illuminate\Database\Query\Builder::load does not exist."
For this case you dont need add scope. Instead if you can add this function in your model
public function loadPermissions($merchantId = null)
{
return $this->load(['permissions' => function ($q) use ($merchantId) {
if ($merchantId) {
$q->where('merchant_user_permission.merchant_id','=', $merchantId);
}
}]);
}
and usage
$merchant_user->loadPermissions($merchantId);

Change dynamically validated_file_class in symfony 1.4

I have this model:
Banner:
columns:
filename: string(255)
url: string(255)
position:
type: enum
values: [top, right]
default: right
and this form:
class BannerForm extends BaseBannerForm
{
public function configure()
{
$this->widgetSchema['filename'] = new sfWidgetFormInputFileEditable(array(
'file_src' => $this->getObject()->getThumbURL(),
'is_image' => true,
'edit_mode' => $this->getObject()->exists()
));
$validated_file_class = $this->getObject()->position === 'right' ? 'bannerRightValidatedFile' : 'bannerTopValidatedFile';
$this->validatorSchema['filename'] = new sfValidatorFile(array(
'path' => sfConfig::get('sf_upload_dir'),
'mime_types' => 'web_images',
'validated_file_class' => $validated_file_class',
'required' => $this->getObject()->isNew()
));
}
}
I use different validate classes because inside it i incapsulate thumbnail operations, and the sizes of banners depends on it position field.
The problem is that $validated_file_class is always bannerRightValidatedFile class.
How i can achieve this thing ?
I can suggest 4 solutions which you can choose from:
Option 1:
You should add a update$fieldNameColumn method to the form class. In your case it should look like this:
// change validated file instance before calling save
protected function updateFilenameColumn($value)
{
if ($value instanceof sfValidatedFile)
{
$class = 'right' == $this->getValue('position') ? 'bannerRightValidatedFile' : 'bannerTopValidatedFile';
// this will not work as I thought at first time
// $this->getValidator('filename')->setOption('validated_file_class', $class);
$this->values['filename'] = new $class(
$value->getOriginalName(),
$value->getType(),
$value->getTempName(),
$value->getSize(),
$value->getPath()
);
return $this->processUploadedFile('filename');
}
return $value;
}
I think it's kind of hacky.
Option 2:
You should add a doctrine hook method to the model:
/**
* #param Doctrine_Event $event
*/
public function postSave($event)
{
$record = $event->getInvoker();
if (array_key_exists('filename', $record->getLastModified()))
{
// get the full path to the file
$file = sfConfig::get('sf_upload_dir') . '/' . $record->getFilename();
if (file_exists($file))
{
// resize the file e.g. with sfImageTransformPlugin
$img = new sfImage($file);
$img
->resize(100, 100)
->save();
}
}
}
This will work when creating records whitout a form e.g. when using fixtures.
Option 3:
Use the admin.save_object event.
public static function listenToAdminSaveObject(sfEvent $event)
{
$record = $event['object'];
if ($event['object'] instanceof Banner)
{
// use the same code as in the `postSave` example
}
}
Option 4:
Use the sfImageTransformExtraPlugin
It's kind of hard to setup and configure (and it's code is a mess :), but it makes possible to modify the size of the image whithout regenerating all the already resized ones.
You could add a sfCallbackValidator as a post-validator, and set the property accordingly.
Pseudo code (I don't have the exact function signatures at hand).
public function configure() {
// ...
$this->mergePostValidator(new sfCallbackValidator(array('callback' => array($this, 'validateFile'))));
}
public function validateFile($values) {
$realValidator = new sfValidatorFile(...);
return $realValidator->clean($values['field']);
}
If you can modify the call to the form class, you can do that:
$form = new BannerForm(array(), array('validated_file_class' => 'bannerRightValidatedFile');
$form2 = new BannerForm(array(), array('validated_file_class' => 'bannerTopValidatedFile');
And then in your form:
class BannerForm extends BaseBannerForm
{
public function configure()
{
$this->widgetSchema['filename'] = new sfWidgetFormInputFileEditable(array(
'file_src' => $this->getObject()->getThumbURL(),
'is_image' => true,
'edit_mode' => $this->getObject()->exists()
));
$this->validatorSchema['filename'] = new sfValidatorFile(array(
'path' => sfConfig::get('sf_upload_dir'),
'mime_types' => 'web_images',
'validated_file_class' => $this->options['validated_file_class'],
'required' => $this->getObject()->isNew()
));
}
}
Edit:
Since you are playing inside the admin gen, I think the best way is to use a postValidator like #Grad van Horck says.
Your validate class depend on an extra field. With a postvalidator, you can access any field inside the form. Then, you just need to create a little switch to handle the case for each position / validated class.
public function configure()
{
// ...
$this->mergePostValidator(new sfValidatorCallback(array('callback' => array($this, 'validateFile'))));
}
public function validateFile($validator, $values, $arguments)
{
$default = array(
'path' => sfConfig::get('sf_upload_dir'),
'mime_types' => 'web_images',
'required' => $this->getObject()->isNew()
);
switch ($values['position'] ) {
case 'right':
$validator = new sfValidatorFile($default + array(
'validated_file_class' => 'bannerRightValidatedFile',
));
break;
case 'top':
$validator = new sfValidatorFile($default + array(
'validated_file_class' => 'bannerTopValidatedFile',
));
default:
# code...
break;
}
$values['filename'] = $validator->clean($values['filename']);
return $values;
}