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
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?
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.
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');
}
}
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);
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;
}