Initial commit
This commit is contained in:
226
app/Models/Forms/Form.php
Normal file
226
app/Models/Forms/Form.php
Normal file
@@ -0,0 +1,226 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models\Forms;
|
||||
|
||||
use App\Events\Models\FormCreated;
|
||||
use App\Models\Integration\FormZapierWebhook;
|
||||
use App\Models\User;
|
||||
use App\Models\Workspace;
|
||||
use Database\Factories\FormFactory;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
use Spatie\Sluggable\HasSlug;
|
||||
use Spatie\Sluggable\SlugOptions;
|
||||
use Stevebauman\Purify\Facades\Purify;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
class Form extends Model
|
||||
{
|
||||
const DARK_MODE_VALUES = ['auto', 'light', 'dark'];
|
||||
const THEMES = ['default', 'simple', 'notion'];
|
||||
const WIDTHS = ['centered', 'full'];
|
||||
|
||||
use HasFactory, HasSlug, SoftDeletes;
|
||||
|
||||
protected $fillable = [
|
||||
'workspace_id',
|
||||
'creator_id',
|
||||
'properties',
|
||||
'removed_properties',
|
||||
|
||||
// Notifications
|
||||
'notifies',
|
||||
'notification_emails',
|
||||
'send_submission_confirmation',
|
||||
'notification_sender',
|
||||
'notification_subject',
|
||||
'notification_body',
|
||||
'notifications_include_submission',
|
||||
|
||||
// integrations
|
||||
'webhook_url',
|
||||
|
||||
'title',
|
||||
'description',
|
||||
'tags',
|
||||
|
||||
// Customization
|
||||
'theme',
|
||||
'width',
|
||||
'cover_picture',
|
||||
'logo_picture',
|
||||
'dark_mode',
|
||||
'color',
|
||||
'uppercase_labels',
|
||||
'no_branding',
|
||||
'hide_title',
|
||||
'transparent_background',
|
||||
|
||||
// Custom Code
|
||||
'custom_code',
|
||||
|
||||
// Submission
|
||||
'submit_button_text',
|
||||
'database_fields_update',
|
||||
're_fillable',
|
||||
're_fill_button_text',
|
||||
'submitted_text',
|
||||
'redirect_url',
|
||||
'use_captcha',
|
||||
'closes_at',
|
||||
'closed_text',
|
||||
'max_submissions_count',
|
||||
'max_submissions_reached_text',
|
||||
|
||||
// Security & Privacy
|
||||
'can_be_indexed',
|
||||
'password'
|
||||
];
|
||||
|
||||
protected $casts = [
|
||||
'properties' => 'array',
|
||||
'database_fields_update' => 'array',
|
||||
'closes_at' => 'datetime',
|
||||
'tags' => 'array',
|
||||
'removed_properties' => 'array'
|
||||
];
|
||||
|
||||
protected $appends = [
|
||||
'share_url',
|
||||
'is_pro'
|
||||
];
|
||||
|
||||
protected $hidden = [
|
||||
'workspace_id',
|
||||
'notifies',
|
||||
'webhook_url',
|
||||
'send_submission_confirmation',
|
||||
'redirect_url',
|
||||
'database_fields_update',
|
||||
'notification_sender',
|
||||
'notification_subject',
|
||||
'notification_body',
|
||||
'notifications_include_submission',
|
||||
'password',
|
||||
'tags',
|
||||
'notification_emails',
|
||||
'removed_properties'
|
||||
];
|
||||
|
||||
/**
|
||||
* The event map for the model.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $dispatchesEvents = [
|
||||
'created' => FormCreated::class,
|
||||
];
|
||||
|
||||
public function getIsProAttribute()
|
||||
{
|
||||
return optional($this->workspace)->is_pro;
|
||||
}
|
||||
|
||||
public function getShareUrlAttribute()
|
||||
{
|
||||
return url('/forms/'.$this->slug);
|
||||
}
|
||||
|
||||
public function getSubmissionsCountAttribute()
|
||||
{
|
||||
return $this->submissions()->count();
|
||||
}
|
||||
|
||||
public function getViewsCountAttribute()
|
||||
{
|
||||
return $this->views()->count() +
|
||||
$this->statistics()->sum(DB::raw("cast(data->>'views' as integer)"));
|
||||
}
|
||||
|
||||
public function setDescriptionAttribute($value)
|
||||
{
|
||||
// Strip out unwanted html
|
||||
$this->attributes['description'] = Purify::clean($value);
|
||||
}
|
||||
|
||||
public function setSubmittedTextAttribute($value)
|
||||
{
|
||||
// Strip out unwanted html
|
||||
$this->attributes['submitted_text'] = Purify::clean($value);
|
||||
}
|
||||
|
||||
public function getIsClosedAttribute()
|
||||
{
|
||||
return ($this->closes_at && now()->gt($this->closes_at));
|
||||
}
|
||||
|
||||
public function getMaxNumberOfSubmissionsReachedAttribute()
|
||||
{
|
||||
return ($this->max_submissions_count && $this->max_submissions_count <= $this->submissions_count);
|
||||
}
|
||||
|
||||
public function setClosedTextAttribute($value)
|
||||
{
|
||||
$this->attributes['closed_text'] = Purify::clean($value);
|
||||
}
|
||||
|
||||
public function setMaxSubmissionsReachedTextAttribute($value)
|
||||
{
|
||||
$this->attributes['max_submissions_reached_text'] = Purify::clean($value);
|
||||
}
|
||||
|
||||
public function getHasPasswordAttribute()
|
||||
{
|
||||
return !empty($this->password);
|
||||
}
|
||||
|
||||
/**
|
||||
* Relationships
|
||||
*/
|
||||
public function workspace()
|
||||
{
|
||||
return $this->belongsTo(Workspace::class);
|
||||
}
|
||||
|
||||
public function creator()
|
||||
{
|
||||
return $this->belongsTo(User::class, 'creator_id');
|
||||
}
|
||||
|
||||
public function submissions()
|
||||
{
|
||||
return $this->hasMany(FormSubmission::class);
|
||||
}
|
||||
|
||||
public function views()
|
||||
{
|
||||
return $this->hasMany(FormView::class);
|
||||
}
|
||||
|
||||
public function statistics()
|
||||
{
|
||||
return $this->hasMany(FormStatistic::class);
|
||||
}
|
||||
|
||||
public function zappierHooks()
|
||||
{
|
||||
return $this->hasMany(FormZapierWebhook::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Config/options
|
||||
*/
|
||||
public function getSlugOptions(): SlugOptions
|
||||
{
|
||||
return SlugOptions::create()
|
||||
->doNotGenerateSlugsOnUpdate()
|
||||
->generateSlugsFrom('title')
|
||||
->saveSlugsTo('slug');
|
||||
}
|
||||
|
||||
public static function newFactory()
|
||||
{
|
||||
return FormFactory::new();
|
||||
}
|
||||
}
|
||||
38
app/Models/Forms/FormStatistic.php
Normal file
38
app/Models/Forms/FormStatistic.php
Normal file
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models\Forms;
|
||||
|
||||
use App\Models\Forms\Form;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class FormStatistic extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
public $timestamps = false;
|
||||
|
||||
protected $fillable = [
|
||||
'form_id',
|
||||
'data',
|
||||
'date'
|
||||
];
|
||||
|
||||
/**
|
||||
* The attributes that should be cast.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $casts = [
|
||||
'data' => 'array',
|
||||
];
|
||||
|
||||
/**
|
||||
* Relationships
|
||||
*/
|
||||
public function form()
|
||||
{
|
||||
return $this->belongsTo(Form::class);
|
||||
}
|
||||
|
||||
}
|
||||
27
app/Models/Forms/FormSubmission.php
Normal file
27
app/Models/Forms/FormSubmission.php
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models\Forms;
|
||||
|
||||
use App\Models\Forms\Form;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class FormSubmission extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
protected $fillable = [
|
||||
'data'
|
||||
];
|
||||
|
||||
protected $casts = [
|
||||
'data' => 'array'
|
||||
];
|
||||
|
||||
/**
|
||||
* RelationShips
|
||||
*/
|
||||
public function form() {
|
||||
return $this->belongsTo(Form::class);
|
||||
}
|
||||
}
|
||||
19
app/Models/Forms/FormView.php
Normal file
19
app/Models/Forms/FormView.php
Normal file
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models\Forms;
|
||||
|
||||
use App\Models\Forms\Form;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class FormView extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
/**
|
||||
* RelationShips
|
||||
*/
|
||||
public function form() {
|
||||
return $this->belongsTo(Form::class);
|
||||
}
|
||||
}
|
||||
37
app/Models/Integration/FormZapierWebhook.php
Normal file
37
app/Models/Integration/FormZapierWebhook.php
Normal file
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models\Integration;
|
||||
|
||||
use App\Models\Forms\Form;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
use Spatie\WebhookServer\WebhookCall;
|
||||
|
||||
class FormZapierWebhook extends Model
|
||||
{
|
||||
use HasFactory, SoftDeletes;
|
||||
|
||||
protected $table = 'form_zapier_webhooks';
|
||||
|
||||
protected $fillable = [
|
||||
'form_id',
|
||||
'hook_url',
|
||||
];
|
||||
|
||||
/**
|
||||
* Relationships
|
||||
*/
|
||||
public function form()
|
||||
{
|
||||
return $this->belongsTo(Form::class);
|
||||
}
|
||||
|
||||
public function triggerHook(array $data) {
|
||||
WebhookCall::create()
|
||||
->url($this->hook_url)
|
||||
->doNotSign()
|
||||
->payload($data)
|
||||
->dispatch();
|
||||
}
|
||||
}
|
||||
39
app/Models/OAuthProvider.php
Normal file
39
app/Models/OAuthProvider.php
Normal file
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class OAuthProvider extends Model
|
||||
{
|
||||
/**
|
||||
* The table associated with the model.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $table = 'oauth_providers';
|
||||
|
||||
/**
|
||||
* The attributes that aren't mass assignable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $guarded = ['id'];
|
||||
|
||||
/**
|
||||
* The attributes that should be hidden for arrays.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $hidden = [
|
||||
'access_token', 'refresh_token',
|
||||
];
|
||||
|
||||
/**
|
||||
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||
*/
|
||||
public function user()
|
||||
{
|
||||
return $this->belongsTo(User::class);
|
||||
}
|
||||
}
|
||||
209
app/Models/User.php
Normal file
209
app/Models/User.php
Normal file
@@ -0,0 +1,209 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Http\Controllers\SubscriptionController;
|
||||
use App\Models\Forms\Form;
|
||||
use App\Models\Workspace;
|
||||
use App\Notifications\ResetPassword;
|
||||
use App\Notifications\VerifyEmail;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Foundation\Auth\User as Authenticatable;
|
||||
|
||||
// use Illuminate\Contracts\Auth\MustVerifyEmail;
|
||||
use Illuminate\Notifications\Notifiable;
|
||||
use Laravel\Cashier\Billable;
|
||||
use Rickycezar\Impersonate\Models\Impersonate;
|
||||
use Tymon\JWTAuth\Contracts\JWTSubject;
|
||||
|
||||
class User extends Authenticatable implements JWTSubject //, MustVerifyEmail
|
||||
{
|
||||
use Notifiable, HasFactory, Billable;
|
||||
|
||||
const ADMINS = ['julien@notionforms.io'];
|
||||
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $fillable = [
|
||||
'name',
|
||||
'email',
|
||||
'password',
|
||||
'hear_about_us'
|
||||
];
|
||||
|
||||
/**
|
||||
* The attributes that should be hidden for arrays.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $hidden = [
|
||||
'password',
|
||||
'remember_token',
|
||||
'hear_about_us'
|
||||
];
|
||||
|
||||
/**
|
||||
* The attributes that should be cast to native types.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $casts = [
|
||||
'email_verified_at' => 'datetime',
|
||||
];
|
||||
|
||||
/**
|
||||
* The accessors to append to the model's array form.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $appends = [
|
||||
'photo_url',
|
||||
'is_subscribed',
|
||||
'has_enterprise_subscription',
|
||||
'admin',
|
||||
'has_customer_id',
|
||||
'has_forms'
|
||||
];
|
||||
|
||||
protected $withCount = ['workspaces'];
|
||||
|
||||
/**
|
||||
* Get the profile photo URL attribute.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getPhotoUrlAttribute()
|
||||
{
|
||||
return vsprintf('https://www.gravatar.com/avatar/%s.jpg?s=200&d=%s', [
|
||||
md5(strtolower($this->email)),
|
||||
$this->name ? urlencode("https://ui-avatars.com/api/$this->name") : 'mp',
|
||||
]);
|
||||
}
|
||||
|
||||
public function getHasFormsAttribute()
|
||||
{
|
||||
return $this->workspaces()->whereHas('forms')->exists();
|
||||
}
|
||||
|
||||
public function getIsSubscribedAttribute()
|
||||
{
|
||||
return $this->subscribed() || $this->subscribed(SubscriptionController::ENTERPRISE_SUBSCRIPTION_NAME);
|
||||
}
|
||||
|
||||
public function getHasEnterpriseSubscriptionAttribute()
|
||||
{
|
||||
return $this->subscribed(SubscriptionController::ENTERPRISE_SUBSCRIPTION_NAME);
|
||||
}
|
||||
|
||||
public function getHasCustomerIdAttribute()
|
||||
{
|
||||
return !is_null($this->stripe_id);
|
||||
}
|
||||
|
||||
public function getAdminAttribute()
|
||||
{
|
||||
return in_array($this->email, self::ADMINS);
|
||||
}
|
||||
|
||||
/**
|
||||
* =================================
|
||||
* Helper Related
|
||||
* =================================
|
||||
*/
|
||||
|
||||
/**
|
||||
* Send the password reset notification.
|
||||
*
|
||||
* @param string $token
|
||||
* @return void
|
||||
*/
|
||||
public function sendPasswordResetNotification($token)
|
||||
{
|
||||
$this->notify(new ResetPassword($token));
|
||||
}
|
||||
|
||||
/**
|
||||
* Send the email verification notification.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function sendEmailVerificationNotification()
|
||||
{
|
||||
$this->notify(new VerifyEmail);
|
||||
}
|
||||
|
||||
/**
|
||||
* =================================
|
||||
* Relationship
|
||||
* =================================
|
||||
*/
|
||||
|
||||
public function workspaces()
|
||||
{
|
||||
return $this->belongsToMany(Workspace::class);
|
||||
}
|
||||
|
||||
public function forms()
|
||||
{
|
||||
return $this->hasMany(Form::class,'creator_id');
|
||||
}
|
||||
|
||||
/**
|
||||
* =================================
|
||||
* Oauth Related
|
||||
* =================================
|
||||
*/
|
||||
|
||||
/**
|
||||
* Get the oauth providers.
|
||||
*
|
||||
* @return \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
*/
|
||||
public function oauthProviders()
|
||||
{
|
||||
return $this->hasMany(OAuthProvider::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getJWTIdentifier()
|
||||
{
|
||||
return $this->getKey();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getJWTCustomClaims()
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
public static function boot ()
|
||||
{
|
||||
parent::boot();
|
||||
static::deleting(function(User $user) {
|
||||
// Remove user's workspace if he's the only one with this workspace
|
||||
foreach ($user->workspaces as $workspace) {
|
||||
if ($workspace->users()->count() == 1) {
|
||||
$workspace->delete();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public function scopeWithActiveSubscription($query)
|
||||
{
|
||||
return $query->whereHas('subscriptions', function($query) {
|
||||
$query->where(function($q){
|
||||
$q->where('stripe_status', 'trialing')
|
||||
->orWhere('stripe_status', 'active');
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
68
app/Models/Workspace.php
Normal file
68
app/Models/Workspace.php
Normal file
@@ -0,0 +1,68 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Models\Forms\Form;
|
||||
use App\Models\User;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class Workspace extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
protected $fillable = [
|
||||
'name',
|
||||
'icon',
|
||||
'user_id',
|
||||
];
|
||||
|
||||
protected $appends = [
|
||||
'is_pro',
|
||||
'is_enterprise'
|
||||
];
|
||||
|
||||
public function getIsProAttribute()
|
||||
{
|
||||
return true; // Temporary true for ALL
|
||||
|
||||
// Make sure at least one owner is pro
|
||||
foreach ($this->owners as $owner) {
|
||||
if ($owner->is_subscribed) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getIsEnterpriseAttribute()
|
||||
{
|
||||
return true; // Temporary true for ALL
|
||||
|
||||
foreach ($this->owners as $owner) {
|
||||
if ($owner->has_enterprise_subscription) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Relationships
|
||||
*/
|
||||
|
||||
public function users()
|
||||
{
|
||||
return $this->belongsToMany(User::class);
|
||||
}
|
||||
|
||||
public function owners()
|
||||
{
|
||||
return $this->users()->wherePivot('role', 'admin');
|
||||
}
|
||||
|
||||
public function forms()
|
||||
{
|
||||
return $this->hasMany(Form::class);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user