2021年4月27日火曜日
さくらインターネットVPS設定
2021年3月2日火曜日
fancy product designerにおけるSVGファイルにlinearGradient情報なくなる対応
linearGradient情報含まれるSVGファイルをfancy product designerに取り込むと、その情報がなくなった。原因はSVG各objectのfillを処理する際のバグ?か
ソースコードの6018行目あたり、objectのfillは、色のHexかtransparentとなるが、linearGradientの場合、fillがobjectになっている。
var color = objects[i].fill.length > 0 ? tinycolor(objects[i].fill).toHexString() : 'transparent';
params.colors.push(color);
対応するには、下記のように変更
if(typeof(objects[i].fill) !== "object") {
var color = objects[i].fill.length > 0 ? tinycolor(objects[i].fill).toHexString() : 'transparent';
params.colors.push(color);
} else {
params.colors.push('');
}
さらに、6070行目あたり
//if no default colors are set, use the initial path colors
else if(!fabricParams.fill && !fabricParams.svgFill) {
if(objects) {
params.colors = [];
for(var i=0; i < objects.length; ++i) {
if(typeof(objects[i].fill) !== "object") {
var color = objects[i].fill.length > 0 ? tinycolor(objects[i].fill).toHexString() : 'transparent';
params.colors.push(color);
} else {
params.colors.push('');
}
}
params.svgFill = params.colors;
}
fabricParams.svgFill = params.svgFill;
}
最後、7540行目あたり
//path groups (svg)
else if(element.type == FPDPathGroupName && typeof hex == 'object') {
for(var i=0; i < hex.length; ++i) {
if(element.getObjects()[i] && hex[i] !== '') {
element.getObjects()[i].set('fill', hex[i]);
}
}
fancy product designerの内容をdownload時SVG対応
fancy product designerの内容をsvgとしてdownload際、画像のsrcがリンクの場合、リンク形式で保存され、AIで開くと参照ファイルがないため、表示できない。
fancy product designerが使うfabricjsのメソッドをoverwriteする必要ある。画像のsrcがbase64形式の場合そのまま、リンクの場合DataURLとして保存する
fabric.Image.prototype.getSvgSrc = function() {
return this.toDataURLforSVG();
};
fabric.Image.prototype.toDataURLforSVG = function(options) {
var src = this._element.src;
var imageParts = src.split('.');
//base64 encodedかどうか
if(imageParts.length == 1) {
return imageParts[0];
}
// base64ではない場合、リンクの場合、base64を返す
var el = fabric.util.createCanvasElement();
el.width = this._element.naturalWidth || this._element.width;
el.height = this._element.naturalHeight || this._element.height;
el.getContext("2d").drawImage(this._element, 0, 0);
var data = el.toDataURL(options);
return data;
};
fancy product designerローカルSVG画像使用時正しく表示されない対応
fancy product designer(https://fancyproductdesigner.com/) jqueryバージョンの最新有料版を使っていますが、ローカルSVGをdesignerに入れると、正しく表示されない。
ソースには、ローカル画像をstageに入れる場合、FileReaderを使用する。
reader.readAsDataURL(file);
ここで、SVGでもDataURL形式で読み込まれる。
addElement functionで、読み込まれた結果をSVGかどうかの判断がありますが、DataURL形式のため、ただしく認識できない。
if(source.search('<svg') !== -1)
解決するには、SVGから変換されたDataURL形式なら、もとのテキストファイルに戻す。
ソースコードの5937行の後に下記追加
if(source.search(/data:image\/svg\+xml;base64,/) >= 0) {
source = atob(source.replace(/^data:image\/svg\+xml;base64,/, ''));
}
2020年12月23日水曜日
メールサーバーをサクラVPS上構築
Postfix のインストール
さくらVPSのCentOSイメージには初期インストールされているので不要。更新を行う
# yum -y update postfix
Dovecot のインストール
# yum install dovecot dovecot-mysqlpostfixadminインストール
# cd /usr/local/src# wget http://nchc.dl.sourceforge.net/sourceforge/postfixadmin/postfixadmin-3.2.tar.gz
# tar xzvf postfixadmin-3.2.tar.gz
# mv postfixadmin-3.2 /var/www/html/postfixadmin
# cd /var/www/html/postfixadmin
# chown apache:apache -R /var/www/html/postfixadmin
# ln -s /var/www/html/postfixadmin/public /var/www/html/mySite/public/postfixadmin
/postfixadmin にアクセスできるように /var/www/html/mySite/public/.htaccess rewrite ruleに下記追加(laravel使用しているため)
RewriteCond %{REQUEST_URI} !^/postfixadmin.*$
postfixadminためのDB設定
postfixadmin設定
postfixadmin setup
mail user用意
postfix設定用ファイル作成
postfix設定
/etc/postfix/main.cfを編集
/etc/postfix/master.cfを編集
postfix再起動(もともと起動されている)
dovecot設定
/etc/dovecot/dovecot.confを編集
/etc/dovecot/conf.d/10-mail.confを編集
/etc/dovecot/conf.d/10-auth.confを編集
/etc/dovecot/conf.d/auth-sql.conf.ext 以下のようになっているか確認
/etc/dovecot/dovecot-sql.conf.extを作成
/etc/dovecot/conf.d/10-master.confを編集
/etc/dovecot/conf.d/10-ssl.conf 編集
Dovecotの起動と自動起動設定
2020年11月18日水曜日
laravel user password reset際、登録済みemailのチェック条件
laravelデフォルトuser table softdelete以外のemailですでに登録済みユーザーかどうか判断する。追加条件で登録済みユーザーを判断したい場面もでてくる。その際、sendResetLinkEmail functionをoverwriteすれば良い。
下記のように、app\Http\Controllers\Auth\ForgotPasswordController.php はtrait SendsPasswordResetEmails(vendor\laravel\framework\src\Illuminate\Foundation\Auth\SendsPasswordResetEmails.php)を使用している。
use SendsPasswordResetEmails
登録済みのemailかどうかについて、sendResetLinkEmail functionの中で行っている。
/**
* overwrite SendsPasswordResetEmails function in ForgotPasswordController.php
*/
public function sendResetLinkEmail(Request $request)
{
$this->validateEmail($request);
$request->merge(['type' => 0]); // 条件追加:type 0のユーザーのみ登録済みかどうか判断
$response = $this->broker()->sendResetLink(
$request->only('email', 'type') // ここでemail以外、type値も追加
);
return $response == Password::RESET_LINK_SENT
? $this->sendResetLinkResponse($request, $response)
: $this->sendResetLinkFailedResponse($request, $response);
}
2020年10月28日水曜日
git remote
git remote add origin https://アカウント名@gitlab.com/アカウント名/プロジェクト名.git
git remote rm origin // 関連性を削除
2020年8月24日月曜日
laravel projectにてhtpasswd でbase認証をかける
1)base認証用password fileを作成
mkdir /etc/htpasswd (必要に応じて)
htpasswd -c /etc/htpasswd/.htpasswd username(コマンドを実行すると、PW入力を要求される)
2)/var/www/html/site/public/.htaccess を変更
一番上に、以下を追加
AuthType Basic
AuthName "Authentication Required"
AuthUserFile "/etc/htpasswd/.htpasswd"
Require valid-user
サクラVPSにSSLを導入
1)certbotインストール
yum install certbot python2-certbot-apache
2)apache confファイルの最後に下記VirtualHost追加
NameVirtualHost *:80
<VirtualHost *:80>
ServerAdmin root@xxx.com
DocumentRoot /var/www/html/site/public
ServerName xxx.com
3)certbotコマンドを実行して証明書をインストール
certbot --apache -d xxx.com
※実施中、httpをhttpsへredirectするか聞いてくる際、redirectするようにします。
初期ドメイン→独自ドメイン リダイレクト
以下の内容をapache confファイルに追加
<VirtualHost *:80>
ServerAdmin root@xxx.com
DocumentRoot /var/www/html/site/public
ServerName os1-234-56789.vs.sakura.ne.jp
RewriteEngine on
RewriteCond %{SERVER_NAME} =os1-234-56789.vs.sakura.ne.jp
RewriteRule ^ https://xxx.com%{REQUEST_URI} [END,NE,R=permanent]
4)証明書を更新
certbot renew
2019年7月5日金曜日
2019年6月3日月曜日
laravel type hintでobjとれない件
Route::resource('tokus', 'TokuController')
controllerで下記のtype hintがあるが、dd($toku)であるはずのobjがとれない。
public function show(Toku $toku)
{
return view('tokus.show', compact('toku'));
}
route:listで確認したところ、show actionのURIは、tokes/{tokes}になっている。
type hintの引数は{tokes}と一致しないといけないため、public function show(Toku $tokus)に変更したら解決できた。それが嫌なら、引数を指定できる。
Route::resource('tokus', 'TokuController')->parameters([
'tokus' => 'toku'
]);
参考:https://laracasts.com/discuss/channels/laravel/controller-method-with-type-hinting-give-empty-eloquent-object
2019年5月30日木曜日
laravel middleware
$this->middleware(function ($request, $next) {
// ...
return $next($request);
});
resource controller
Route::resource('photos', 'PhotoController');
Route::resources([
'photos' => 'PhotoController',
'posts' => 'PostController'
]);
Partial Resource Routes
Route::resource('photos', 'PhotoController')->only(['index', 'show'
]);
Route::resource('photos', 'PhotoController')->except([
'create', 'store', 'update', 'destroy'
]);
Route::apiResources([
'photos' => 'PhotoController',
'posts' => 'PostController'
]);
If you need to add additional routes to a resource controller beyond the default set of resource routes, you should define those routes before your call to Route::resource
Route::get('photos/popular', 'PhotoController@method');
Route::resource('photos', 'PhotoController');
You may even restrict the middleware to only certain methods on the controller class:
public function __construct()
{
$this->middleware('auth');
$this->middleware('log')->only('index');
$this->middleware('subscribed')->except('store');
}
// 一覧
GET /projects (index)
// 新規ページ
GET /projects/create (create)
// 保存
POST /projects (store)
// show project
GET /projects/{id}
// 編集ページ
GET /projects/{id}/edit (edit)
// 更新
PATCH /projects/{id} (update)
// 削除
DELETE /projects/{id} (destroy)
Dependency Injection & Controllers
laravel Authorization
Gates are most applicable to actions which are not related to any model or resource, such as viewing an administrator dashboard. In contrast, policies should be used when you wish to authorize an action for a particular model or resource.
Gates are Closures that determine if a user is authorized to perform a given action and are typically defined in the App\Providers\AuthServiceProvider class using the Gate facade. Gates always receive a user instance as their first argument, and may optionally receive additional arguments such as a relevant Eloquent model:
public function boot()
{
$this->registerPolicies();
Gate::define('update-post', function ($user, $post) {
return $user->id == $post->user_id;
});
Gate::define('update-post', 'App\Policies\PostPolicy@update');
}
Authorizing Actions
To authorize an action using gates, you should use the allows or denies methods. Note that you are not required to pass the currently authenticated user to these methods. Laravel will automatically take care of passing the user into the gate Closure:if (Gate::allows('update-post', $post)) {
// The current user can update the post...
}
if (Gate::denies('update-post', $post)) {
// The current user can't update the post...
}
If you would like to determine if a particular user is authorized to perform an action, you may use the forUser method on the Gate facade:
if (Gate::forUser($user)->allows('update-post', $post)) {
// The user can update the post...
}
if (Gate::forUser($user)->denies('update-post', $post)) {
// The user can't update the post...
}
You may use the before method to define a callback that is run before all other authorization checks:
boot function中で下記追加
Gate::before(function ($user, $ability) {
if ($user->isSuperAdmin()) {
return true;
}
});
If the before callback returns a non-null result that result will be considered the result of the check.
You may use the after method to define a callback to be executed after all other authorization checks:
Gate::after(function ($user, $ability, $result, $arguments) {
if ($user->isSuperAdmin()) {
return true;
}
});
Generating Policies
Registering Policies
Guest Users
public function update(?User $user, Post $post)
{
return $user->id === $post->user_id;
}
For certain users, you may wish to authorize all actions within a given policy. To accomplish this, define a before method on the policy. The before method will be executed before any other methods on the policy
public function before($user, $ability)
{
if ($user->isSuperAdmin()) {
return true;
}
}
If you would like to deny all authorizations for a user you should return false from the before method. If null is returned, the authorization will fall through to the policy method.
The before method of a policy class will not be called if the class doesn't contain a method with a name matching the name of the ability being checked.
Authorizing Actions Using Policies
if ($user->can('update', $post)) {// Via The User Model
}
use App\Post;
if ($user->can('create', Post::class)) {
// Executes the "create" method on the relevant policy...
}
Laravel includes a middleware that can authorize actions before the incoming request even reaches your routes or controllers.
Route::put('/post/{post}', function (Post $post) {
// The current user may update the post...
})->middleware('can:update,post');
we're passing the can middleware two arguments. The first is the name of the action we wish to authorize and the second is the route parameter we wish to pass to the policy method.
Actions That Don't Require Model Instance
Route::post('/post', function () {
// The current user may create posts...
})->middleware('can:create,App\Post');
Via Controller Helpers
public function update(Request $request, Post $post){
$this->authorize('update', $post);
// The current user can update the blog post...
}
Via Blade Templates
2019年5月29日水曜日
laravelのdata_setでarrayの値をobjに代入
$row = new \App\Model();
if ($request->old()) {
foreach (old() as $key => $value) {
data_set($row, $key, $value);
}
}
2019年5月28日火曜日
laravel session
Retrieving Data
There are two primary ways of working with session data in Laravel: the global session helper and via a Request instance.$value = $request->session()->get('key');
$value = $request->session()->get('key', 'default');
$value = $request->session()->get('key', function () {
return 'default';
});
// Retrieve a piece of data from the session...
$value = session('key');
// Specifying a default value...
$value = session('key', 'default');
$data = $request->session()->all();
The has method returns true if the item is present and is not null
if ($request->session()->has('users')) {
//
}
The exists method returns true if the item is present, even if its value is null:
if ($request->session()->exists('users')) {
//
}
Storing Data
Pushing To Array Session Values
Retrieving & Deleting An Item
Flash Data
Deleting Data
2019年5月27日月曜日
laravel paginate
$users = App\User::paginate(15);
"Simple Pagination"
If you only need to display simple "Next" and "Previous" links in your pagination view, you may use the simplePaginate method to perform a more efficient query.$users = DB::table('users')->simplePaginate(15);
$users = User::where('votes', '>', 100)->simplePaginate(15);
Displaying Pagination Results
Customizing The Pagination View
laravel Authentication
LoginController, RegisterController, ResetPasswordController, and VerificationController:
protected $redirectTo = '/';
modify the RedirectIfAuthenticated middleware's handle method to use your new URI when redirecting the user.
you may access the authenticated user via the Auth facade:
// Get the currently authenticated user...
$user = Auth::user(); // auth()->user()
// Get the currently authenticated user's ID...
$id = Auth::id(); // auth()->id()
public function update(Request $request)
{
// $request->user() returns an instance of the authenticated user...
}
if (Auth::check()) { // auth()->check() auth()->guest()
// The user is logged in...
}
Route::get('profile', function () {
// Only authenticated users may enter...
})->middleware('auth');
If you are using controllers, you may call the middleware method from the controller's constructor instead of attaching it in the route definition directly:
public function __construct()
{
$this->middleware('auth');
}
Manually Authenticating Users
public function authenticate(Request $request){
$credentials = $request->only('email', 'password');
if (Auth::attempt($credentials)) {
// Authentication passed...
return redirect()->intended('dashboard');
}
}
The intended method on the redirector will redirect the user to the URL they were attempting to access before being intercepted by the authentication middleware. A fallback URI may be given to this method in case the intended destination is not available.
Auth::logout();
Remembering Users
Your users table must include the string remember_token column, which will be used to store the "remember me" token.if (Auth::attempt(['email' => $email, 'password' => $password], $remember)) {
// The user is being remembered...
}
If you are "remembering" users, you may use the viaRemember method to determine if the user was authenticated using the "remember me" cookie:
if (Auth::viaRemember()) {
//
}
2019年5月20日月曜日
laravel soft delete
namespace App;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class Flight extends Model
{
use SoftDeletes;
}
Schema::table('flights', function (Blueprint $table) {
$table->softDeletes();
});
when you call the delete method on the model, the deleted_at column will be set to the current date and time. And, when querying a model that uses soft deletes, the soft deleted models will automatically be excluded from all query results.
To determine if a given model instance has been soft deleted, use the trashed method:
if ($flight->trashed()) {
//
}
you may force soft deleted models to appear in a result set using the withTrashed method on the query:
$flights = App\Flight::withTrashed()
->where('account_id', 1)
->get();
onlyTrashed method will retrieve only soft deleted models:
$flights = App\Flight::onlyTrashed()
->where('airline_id', 1)
->get();
Sometimes you may wish to "un-delete" a soft deleted model. To restore a soft deleted model into an active state, use the restore method on a model instance:
$flight->restore();
You may also use the restore method in a query to quickly restore multiple models. Again, like other "mass" operations, this will not fire any model events for the models that are restored:
App\Flight::withTrashed()
->where('airline_id', 1)
->restore();
Sometimes you may need to truly remove a model from your database. To permanently remove a soft deleted model from the database, use the forceDelete method:
// Force deleting a single model instance...
$flight->forceDelete();
laravel db migrate
php artisan migrate:rollback
php artisan migrate:rollback --step=5 // rollback the last five migrations
php artisan migrate:reset // roll back all of your application's migrations
roll back all of your migrations and then execute the migrate command. This command effectively re-creates your entire database:
php artisan migrate:refresh
php artisan migrate:refresh --step=5
//drop all tables and re-run all migrations
php artisan migrate:fresh