mirror of
https://github.com/pixelfed/pixelfed.git
synced 2024-11-21 14:01:27 +00:00
Apply fixes from StyleCI
This commit is contained in:
parent
75de27f482
commit
b8abbdd90f
261 changed files with 3368 additions and 3231 deletions
|
@ -2,9 +2,9 @@
|
|||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use Illuminate\Console\Command;
|
||||
use App\Media;
|
||||
use App\Jobs\ImageOptimizePipeline\ImageOptimize;
|
||||
use App\Media;
|
||||
use Illuminate\Console\Command;
|
||||
|
||||
class CatchUnoptimizedMedia extends Command
|
||||
{
|
||||
|
|
|
@ -2,9 +2,10 @@
|
|||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\{Follower, Profile};
|
||||
use Illuminate\Console\Command;
|
||||
use App\Follower;
|
||||
use App\Jobs\FollowPipeline\FollowPipeline;
|
||||
use App\Profile;
|
||||
use Illuminate\Console\Command;
|
||||
|
||||
class SeedFollows extends Command
|
||||
{
|
||||
|
@ -46,7 +47,7 @@ class SeedFollows extends Command
|
|||
$actor = Profile::inRandomOrder()->firstOrFail();
|
||||
$target = Profile::inRandomOrder()->firstOrFail();
|
||||
|
||||
$follow = new Follower;
|
||||
$follow = new Follower();
|
||||
$follow->profile_id = $actor->id;
|
||||
$follow->following_id = $target->id;
|
||||
$follow->save();
|
||||
|
|
|
@ -20,6 +20,7 @@ class Kernel extends ConsoleKernel
|
|||
* Define the application's command schedule.
|
||||
*
|
||||
* @param \Illuminate\Console\Scheduling\Schedule $schedule
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function schedule(Schedule $schedule)
|
||||
|
|
|
@ -10,6 +10,7 @@ class EmailVerification extends Model
|
|||
{
|
||||
$base = config('app.url');
|
||||
$path = '/i/confirm-email/'.$this->user_token.'/'.$this->random_token;
|
||||
|
||||
return "{$base}{$path}";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,14 +2,11 @@
|
|||
|
||||
namespace App\Events;
|
||||
|
||||
use Illuminate\Broadcasting\Channel;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Illuminate\Broadcasting\PrivateChannel;
|
||||
use Illuminate\Broadcasting\PresenceChannel;
|
||||
use Illuminate\Foundation\Events\Dispatchable;
|
||||
use App\User;
|
||||
use App\UserSetting;
|
||||
use Illuminate\Broadcasting\InteractsWithSockets;
|
||||
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
|
||||
use App\{User, UserSetting};
|
||||
use Illuminate\Foundation\Events\Dispatchable;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
class AuthLoginEvent
|
||||
{
|
||||
|
@ -28,7 +25,7 @@ class AuthLoginEvent
|
|||
public function handle(User $user)
|
||||
{
|
||||
if (empty($user->settings)) {
|
||||
$settings = new UserSetting;
|
||||
$settings = new UserSetting();
|
||||
$settings->user_id = $user->id;
|
||||
$settings->save();
|
||||
}
|
||||
|
|
|
@ -30,6 +30,7 @@ class Handler extends ExceptionHandler
|
|||
* Report or log an exception.
|
||||
*
|
||||
* @param \Exception $exception
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function report(Exception $exception)
|
||||
|
@ -42,6 +43,7 @@ class Handler extends ExceptionHandler
|
|||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Exception $exception
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function render($request, Exception $exception)
|
||||
|
|
|
@ -24,6 +24,7 @@ class Follower extends Model
|
|||
public function toText()
|
||||
{
|
||||
$actorName = $this->actor->username;
|
||||
|
||||
return "{$actorName} ".__('notification.startedFollowingYou');
|
||||
}
|
||||
|
||||
|
@ -31,6 +32,7 @@ class Follower extends Model
|
|||
{
|
||||
$actorName = $this->actor->username;
|
||||
$actorUrl = $this->actor->url();
|
||||
|
||||
return "<a href='{$actorUrl}' class='profile-link'>{$actorName}</a> ".
|
||||
__('notification.startedFollowingYou');
|
||||
}
|
||||
|
|
|
@ -24,5 +24,4 @@ class Hashtag extends Model
|
|||
{
|
||||
return config('routes.hashtag.base').$this->slug;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -2,23 +2,24 @@
|
|||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Carbon\Carbon;
|
||||
use App\EmailVerification;
|
||||
use App\Mail\ConfirmEmail;
|
||||
use Auth, DB, Cache, Mail, Redis;
|
||||
use App\{
|
||||
EmailVerification,
|
||||
Notification,
|
||||
Profile,
|
||||
User,
|
||||
UserFilter
|
||||
};
|
||||
use App\Notification;
|
||||
use App\Profile;
|
||||
use App\User;
|
||||
use App\UserFilter;
|
||||
use Auth;
|
||||
use Cache;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Http\Request;
|
||||
use Mail;
|
||||
use Redis;
|
||||
|
||||
class AccountController extends Controller
|
||||
{
|
||||
protected $filters = [
|
||||
'user.mute',
|
||||
'user.block'
|
||||
'user.block',
|
||||
];
|
||||
|
||||
public function __construct()
|
||||
|
@ -89,12 +90,11 @@ class AccountController extends Controller
|
|||
EmailVerification::whereUserId(Auth::id())->delete();
|
||||
}
|
||||
|
||||
|
||||
$user = User::whereNull('email_verified_at')->find(Auth::id());
|
||||
$utoken = hash('sha512', $user->id);
|
||||
$rtoken = str_random(40);
|
||||
|
||||
$verify = new EmailVerification;
|
||||
$verify = new EmailVerification();
|
||||
$verify->user_id = $user->id;
|
||||
$verify->email = $user->email;
|
||||
$verify->user_token = $utoken;
|
||||
|
@ -116,6 +116,7 @@ class AccountController extends Controller
|
|||
$user = User::find(Auth::id());
|
||||
$user->email_verified_at = Carbon::now();
|
||||
$user->save();
|
||||
|
||||
return redirect('/');
|
||||
}
|
||||
}
|
||||
|
@ -142,6 +143,7 @@ class AccountController extends Controller
|
|||
foreach ($keys as $key) {
|
||||
$notifications->push(Cache::get("{$prefix}{$key}"));
|
||||
}
|
||||
|
||||
return $notifications;
|
||||
}
|
||||
|
||||
|
@ -150,7 +152,6 @@ class AccountController extends Controller
|
|||
return view('account.messages');
|
||||
}
|
||||
|
||||
|
||||
public function showMessage(Request $request, $id)
|
||||
{
|
||||
return view('account.message');
|
||||
|
@ -160,7 +161,7 @@ class AccountController extends Controller
|
|||
{
|
||||
$this->validate($request, [
|
||||
'type' => 'required|string',
|
||||
'item' => 'required|integer|min:1'
|
||||
'item' => 'required|integer|min:1',
|
||||
]);
|
||||
|
||||
$user = Auth::user()->profile;
|
||||
|
@ -184,7 +185,7 @@ class AccountController extends Controller
|
|||
break;
|
||||
|
||||
default:
|
||||
# code...
|
||||
// code...
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -192,18 +193,17 @@ class AccountController extends Controller
|
|||
'user_id' => $user->id,
|
||||
'filterable_id' => $filterable['id'],
|
||||
'filterable_type' => $filterable['type'],
|
||||
'filter_type' => 'mute'
|
||||
'filter_type' => 'mute',
|
||||
]);
|
||||
|
||||
return redirect()->back();
|
||||
|
||||
}
|
||||
|
||||
public function block(Request $request)
|
||||
{
|
||||
$this->validate($request, [
|
||||
'type' => 'required|string',
|
||||
'item' => 'required|integer|min:1'
|
||||
'item' => 'required|integer|min:1',
|
||||
]);
|
||||
|
||||
$user = Auth::user()->profile;
|
||||
|
@ -223,7 +223,7 @@ class AccountController extends Controller
|
|||
break;
|
||||
|
||||
default:
|
||||
# code...
|
||||
// code...
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -231,11 +231,9 @@ class AccountController extends Controller
|
|||
'user_id' => $user->id,
|
||||
'filterable_id' => $filterable['id'],
|
||||
'filterable_type' => $filterable['type'],
|
||||
'filter_type' => 'block'
|
||||
'filter_type' => 'block',
|
||||
]);
|
||||
|
||||
return redirect()->back();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -2,17 +2,16 @@
|
|||
|
||||
namespace App\Http\Controllers\Admin;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use App\Report;
|
||||
use Carbon\Carbon;
|
||||
use App\{Comment, Like, Media, Profile, Report, Status, User};
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
trait AdminReportController
|
||||
{
|
||||
public function updateReport(Request $request, $id)
|
||||
{
|
||||
$this->validate($request, [
|
||||
'action' => 'required|string'
|
||||
'action' => 'required|string',
|
||||
]);
|
||||
|
||||
$action = $request->input('action');
|
||||
|
@ -23,7 +22,7 @@ trait AdminReportController
|
|||
'unlist',
|
||||
'delete',
|
||||
'shadowban',
|
||||
'ban'
|
||||
'ban',
|
||||
];
|
||||
|
||||
if (!in_array($action, $actions)) {
|
||||
|
|
|
@ -2,8 +2,10 @@
|
|||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Media;
|
||||
use App\Status;
|
||||
use App\User;
|
||||
use Illuminate\Http\Request;
|
||||
use App\{Comment, Like, Media, Profile, Status, User};
|
||||
|
||||
class AdminController extends Controller
|
||||
{
|
||||
|
@ -20,25 +22,28 @@ class AdminController extends Controller
|
|||
public function users(Request $request)
|
||||
{
|
||||
$users = User::orderBy('id', 'desc')->paginate(10);
|
||||
|
||||
return view('admin.users.home', compact('users'));
|
||||
}
|
||||
|
||||
|
||||
public function statuses(Request $request)
|
||||
{
|
||||
$statuses = Status::orderBy('id', 'desc')->paginate(10);
|
||||
|
||||
return view('admin.statuses.home', compact('statuses'));
|
||||
}
|
||||
|
||||
public function showStatus(Request $request, $id)
|
||||
{
|
||||
$status = Status::findOrFail($id);
|
||||
|
||||
return view('admin.statuses.show', compact('status'));
|
||||
}
|
||||
|
||||
public function media(Request $request)
|
||||
{
|
||||
$media = Status::whereHas('media')->orderby('id', 'desc')->paginate(12);
|
||||
|
||||
return view('admin.media.home', compact('media'));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,23 +2,17 @@
|
|||
|
||||
namespace App\Http\Controllers\Api;
|
||||
|
||||
use Auth, Cache;
|
||||
use App\{
|
||||
Avatar,
|
||||
Like,
|
||||
Profile,
|
||||
Status
|
||||
};
|
||||
use League\Fractal;
|
||||
use Illuminate\Http\Request;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Avatar;
|
||||
use App\Http\Controllers\AvatarController;
|
||||
use App\Util\Webfinger\Webfinger;
|
||||
use App\Transformer\Api\{
|
||||
AccountTransformer,
|
||||
StatusTransformer
|
||||
};
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Jobs\AvatarPipeline\AvatarOptimize;
|
||||
use App\Profile;
|
||||
use App\Transformer\Api\AccountTransformer;
|
||||
use App\Transformer\Api\StatusTransformer;
|
||||
use Auth;
|
||||
use Cache;
|
||||
use Illuminate\Http\Request;
|
||||
use League\Fractal;
|
||||
use League\Fractal\Serializer\ArraySerializer;
|
||||
|
||||
class BaseApiController extends Controller
|
||||
|
@ -35,8 +29,9 @@ class BaseApiController extends Controller
|
|||
public function accounts(Request $request, $id)
|
||||
{
|
||||
$profile = Profile::findOrFail($id);
|
||||
$resource = new Fractal\Resource\Item($profile, new AccountTransformer);
|
||||
$resource = new Fractal\Resource\Item($profile, new AccountTransformer());
|
||||
$res = $this->fractal->createData($resource)->toArray();
|
||||
|
||||
return response()->json($res, 200, [], JSON_PRETTY_PRINT);
|
||||
}
|
||||
|
||||
|
@ -44,8 +39,9 @@ class BaseApiController extends Controller
|
|||
{
|
||||
$profile = Profile::findOrFail($id);
|
||||
$followers = $profile->followers;
|
||||
$resource = new Fractal\Resource\Collection($followers, new AccountTransformer);
|
||||
$resource = new Fractal\Resource\Collection($followers, new AccountTransformer());
|
||||
$res = $this->fractal->createData($resource)->toArray();
|
||||
|
||||
return response()->json($res, 200, [], JSON_PRETTY_PRINT);
|
||||
}
|
||||
|
||||
|
@ -53,8 +49,9 @@ class BaseApiController extends Controller
|
|||
{
|
||||
$profile = Profile::findOrFail($id);
|
||||
$following = $profile->following;
|
||||
$resource = new Fractal\Resource\Collection($following, new AccountTransformer);
|
||||
$resource = new Fractal\Resource\Collection($following, new AccountTransformer());
|
||||
$res = $this->fractal->createData($resource)->toArray();
|
||||
|
||||
return response()->json($res, 200, [], JSON_PRETTY_PRINT);
|
||||
}
|
||||
|
||||
|
@ -62,17 +59,18 @@ class BaseApiController extends Controller
|
|||
{
|
||||
$profile = Profile::findOrFail($id);
|
||||
$statuses = $profile->statuses()->orderBy('id', 'desc')->paginate(20);
|
||||
$resource = new Fractal\Resource\Collection($statuses, new StatusTransformer);
|
||||
$resource = new Fractal\Resource\Collection($statuses, new StatusTransformer());
|
||||
$res = $this->fractal->createData($resource)->toArray();
|
||||
|
||||
return response()->json($res, 200, [], JSON_PRETTY_PRINT);
|
||||
}
|
||||
|
||||
|
||||
public function followSuggestions(Request $request)
|
||||
{
|
||||
$followers = Auth::user()->profile->recommendFollowers();
|
||||
$resource = new Fractal\Resource\Collection($followers, new AccountTransformer);
|
||||
$resource = new Fractal\Resource\Collection($followers, new AccountTransformer());
|
||||
$res = $this->fractal->createData($resource)->toArray();
|
||||
|
||||
return response()->json($res);
|
||||
}
|
||||
|
||||
|
@ -81,6 +79,7 @@ class BaseApiController extends Controller
|
|||
$this->validate($request, [
|
||||
'upload' => 'required|mimes:jpeg,png,gif|max:2000',
|
||||
]);
|
||||
|
||||
try {
|
||||
$user = Auth::user();
|
||||
$profile = $user->profile;
|
||||
|
@ -107,7 +106,7 @@ class BaseApiController extends Controller
|
|||
|
||||
return response()->json([
|
||||
'code' => 200,
|
||||
'msg' => 'Avatar successfully updated'
|
||||
'msg' => 'Avatar successfully updated',
|
||||
]);
|
||||
}
|
||||
}
|
|
@ -2,14 +2,14 @@
|
|||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Auth, Cache;
|
||||
use App\{Like, Status};
|
||||
use Illuminate\Http\Request;
|
||||
use App\Http\Controllers\Api\BaseApiController;
|
||||
use App\Like;
|
||||
use Auth;
|
||||
use Cache;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class ApiController extends BaseApiController
|
||||
{
|
||||
|
||||
public function hydrateLikes(Request $request)
|
||||
{
|
||||
$this->validate($request, [
|
||||
|
@ -30,6 +30,5 @@ class ApiController extends BaseApiController
|
|||
|
||||
public function loadMoreComments(Request $request)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,8 +2,9 @@
|
|||
|
||||
namespace App\Http\Controllers\Auth;
|
||||
|
||||
use App\{AccountLog, User};
|
||||
use App\AccountLog;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\User;
|
||||
use Illuminate\Foundation\Auth\AuthenticatesUsers;
|
||||
|
||||
class LoginController extends Controller
|
||||
|
@ -42,6 +43,7 @@ class LoginController extends Controller
|
|||
* Validate the user login request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function validateLogin($request)
|
||||
|
@ -63,11 +65,12 @@ class LoginController extends Controller
|
|||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param mixed $user
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
protected function authenticated($request, $user)
|
||||
{
|
||||
$log = new AccountLog;
|
||||
$log = new AccountLog();
|
||||
$log->user_id = $user->id;
|
||||
$log->item_id = $user->id;
|
||||
$log->item_type = 'App\User';
|
||||
|
|
|
@ -2,12 +2,12 @@
|
|||
|
||||
namespace App\Http\Controllers\Auth;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\User;
|
||||
use App\Util\Lexer\RestrictedNames;
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Foundation\Auth\RegistersUsers;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use Illuminate\Foundation\Auth\RegistersUsers;
|
||||
|
||||
class RegisterController extends Controller
|
||||
{
|
||||
|
@ -46,6 +46,7 @@ class RegisterController extends Controller
|
|||
* Get a validator for an incoming registration request.
|
||||
*
|
||||
* @param array $data
|
||||
*
|
||||
* @return \Illuminate\Contracts\Validation\Validator
|
||||
*/
|
||||
protected function validator(array $data)
|
||||
|
@ -61,7 +62,7 @@ class RegisterController extends Controller
|
|||
if (!ctype_alpha($value[0])) {
|
||||
return $fail($attribute.' is invalid. Username must be alpha-numeric and start with a letter.');
|
||||
}
|
||||
}
|
||||
},
|
||||
];
|
||||
|
||||
$rules = [
|
||||
|
@ -82,6 +83,7 @@ class RegisterController extends Controller
|
|||
* Create a new user instance after a valid registration.
|
||||
*
|
||||
* @param array $data
|
||||
*
|
||||
* @return \App\User
|
||||
*/
|
||||
protected function create(array $data)
|
||||
|
|
|
@ -2,10 +2,12 @@
|
|||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Auth, Cache, Log, Storage;
|
||||
use App\Avatar;
|
||||
use App\Jobs\AvatarPipeline\AvatarOptimize;
|
||||
use Auth;
|
||||
use Cache;
|
||||
use Illuminate\Http\Request;
|
||||
use Storage;
|
||||
|
||||
class AvatarController extends Controller
|
||||
{
|
||||
|
@ -17,8 +19,9 @@ class AvatarController extends Controller
|
|||
public function store(Request $request)
|
||||
{
|
||||
$this->validate($request, [
|
||||
'avatar' => 'required|mimes:jpeg,png|max:2000'
|
||||
'avatar' => 'required|mimes:jpeg,png|max:2000',
|
||||
]);
|
||||
|
||||
try {
|
||||
$user = Auth::user();
|
||||
$profile = $user->profile;
|
||||
|
@ -42,6 +45,7 @@ class AvatarController extends Controller
|
|||
AvatarOptimize::dispatch($user->profile, $currentAvatar);
|
||||
} catch (Exception $e) {
|
||||
}
|
||||
|
||||
return redirect()->back()->with('status', 'Avatar updated successfully. It may take a few minutes to update across the site.');
|
||||
}
|
||||
|
||||
|
@ -90,6 +94,7 @@ class AvatarController extends Controller
|
|||
$this->checkDir($prefix);
|
||||
}
|
||||
}
|
||||
|
||||
return $avatarpath;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,8 +2,9 @@
|
|||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Bookmark;
|
||||
use App\Status;
|
||||
use Auth;
|
||||
use App\{Bookmark, Profile, Status};
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class BookmarkController extends Controller
|
||||
|
@ -16,7 +17,7 @@ class BookmarkController extends Controller
|
|||
public function store(Request $request)
|
||||
{
|
||||
$this->validate($request, [
|
||||
'item' => 'required|integer|min:1'
|
||||
'item' => 'required|integer|min:1',
|
||||
]);
|
||||
|
||||
$profile = Auth::user()->profile;
|
||||
|
@ -38,5 +39,4 @@ class BookmarkController extends Controller
|
|||
|
||||
return $response;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -2,19 +2,21 @@
|
|||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use App\Comment;
|
||||
use App\Jobs\CommentPipeline\CommentPipeline;
|
||||
use App\Jobs\StatusPipeline\NewStatusPipeline;
|
||||
use Auth, Hashids;
|
||||
use App\{Comment, Profile, Status};
|
||||
use App\Profile;
|
||||
use App\Status;
|
||||
use Auth;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class CommentController extends Controller
|
||||
{
|
||||
|
||||
public function show(Request $request, $username, int $id, int $cid)
|
||||
{
|
||||
$user = Profile::whereUsername($username)->firstOrFail();
|
||||
$status = Status::whereProfileId($user->id)->whereInReplyToId($id)->findOrFail($cid);
|
||||
|
||||
return view('status.reply', compact('user', 'status'));
|
||||
}
|
||||
|
||||
|
@ -23,15 +25,18 @@ class CommentController extends Controller
|
|||
$user = Profile::whereUsername($username)->firstOrFail();
|
||||
$status = Status::whereProfileId($user->id)->findOrFail($id);
|
||||
$replies = Status::whereInReplyToId($id)->paginate(40);
|
||||
|
||||
return view('status.comments', compact('user', 'status', 'replies'));
|
||||
}
|
||||
|
||||
public function store(Request $request)
|
||||
{
|
||||
if(Auth::check() === false) { abort(403); }
|
||||
if (Auth::check() === false) {
|
||||
abort(403);
|
||||
}
|
||||
$this->validate($request, [
|
||||
'item' => 'required|integer',
|
||||
'comment' => 'required|string|max:500'
|
||||
'comment' => 'required|string|max:500',
|
||||
]);
|
||||
$comment = $request->input('comment');
|
||||
$statusId = $request->item;
|
||||
|
|
|
@ -2,10 +2,10 @@
|
|||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Foundation\Bus\DispatchesJobs;
|
||||
use Illuminate\Routing\Controller as BaseController;
|
||||
use Illuminate\Foundation\Validation\ValidatesRequests;
|
||||
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
|
||||
use Illuminate\Foundation\Bus\DispatchesJobs;
|
||||
use Illuminate\Foundation\Validation\ValidatesRequests;
|
||||
use Illuminate\Routing\Controller as BaseController;
|
||||
|
||||
class Controller extends BaseController
|
||||
{
|
||||
|
|
|
@ -2,9 +2,12 @@
|
|||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use App\{Hashtag, Follower, Profile, Status, StatusHashtag};
|
||||
use App\Follower;
|
||||
use App\Hashtag;
|
||||
use App\Profile;
|
||||
use App\Status;
|
||||
use Auth;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class DiscoverController extends Controller
|
||||
{
|
||||
|
@ -38,7 +41,7 @@ class DiscoverController extends Controller
|
|||
public function showTags(Request $request, $hashtag)
|
||||
{
|
||||
$this->validate($request, [
|
||||
'page' => 'nullable|integer|min:1|max:10'
|
||||
'page' => 'nullable|integer|min:1|max:10',
|
||||
]);
|
||||
|
||||
$tag = Hashtag::with('posts')
|
||||
|
|
|
@ -2,19 +2,17 @@
|
|||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Auth, Cache;
|
||||
use App\Jobs\InboxPipeline\InboxWorker;
|
||||
use App\Jobs\RemoteFollowPipeline\RemoteFollowPipeline;
|
||||
use App\Profile;
|
||||
use Carbon\Carbon;
|
||||
use League\Fractal;
|
||||
use Illuminate\Http\Request;
|
||||
use App\Transformer\ActivityPub\ProfileOutbox;
|
||||
use App\Util\Lexer\Nickname;
|
||||
use App\Util\Webfinger\Webfinger;
|
||||
use App\Transformer\ActivityPub\{
|
||||
ProfileOutbox,
|
||||
ProfileTransformer
|
||||
};
|
||||
use App\Jobs\RemoteFollowPipeline\RemoteFollowPipeline;
|
||||
use App\Jobs\InboxPipeline\InboxWorker;
|
||||
use Auth;
|
||||
use Cache;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Http\Request;
|
||||
use League\Fractal;
|
||||
|
||||
class FederationController extends Controller
|
||||
{
|
||||
|
@ -29,16 +27,18 @@ class FederationController extends Controller
|
|||
{
|
||||
$this->authCheck();
|
||||
$this->validate($request, [
|
||||
'acct' => 'required|string|min:3|max:255'
|
||||
'acct' => 'required|string|min:3|max:255',
|
||||
]);
|
||||
$acct = $request->input('acct');
|
||||
$nickname = Nickname::normalizeProfileUrl($acct);
|
||||
|
||||
return view('federation.authorizefollow', compact('acct', 'nickname'));
|
||||
}
|
||||
|
||||
public function remoteFollow()
|
||||
{
|
||||
$this->authCheck();
|
||||
|
||||
return view('federation.remotefollow');
|
||||
}
|
||||
|
||||
|
@ -46,7 +46,7 @@ class FederationController extends Controller
|
|||
{
|
||||
$this->authCheck();
|
||||
$this->validate($request, [
|
||||
'url' => 'required|string'
|
||||
'url' => 'required|string',
|
||||
]);
|
||||
|
||||
if (config('pixelfed.remote_follow_enabled') !== true) {
|
||||
|
@ -67,10 +67,11 @@ class FederationController extends Controller
|
|||
'links' => [
|
||||
[
|
||||
'href' => config('pixelfed.nodeinfo.url'),
|
||||
'rel' => 'http://nodeinfo.diaspora.software/ns/schema/2.0'
|
||||
]
|
||||
]
|
||||
'rel' => 'http://nodeinfo.diaspora.software/ns/schema/2.0',
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
return response()->json($res);
|
||||
}
|
||||
|
||||
|
@ -83,20 +84,20 @@ class FederationController extends Controller
|
|||
'software' => [
|
||||
'homepage' => 'https://pixelfed.org',
|
||||
'github' => 'https://github.com/pixelfed',
|
||||
'follow' => 'https://mastodon.social/@pixelfed'
|
||||
'follow' => 'https://mastodon.social/@pixelfed',
|
||||
],
|
||||
],
|
||||
'openRegistrations' => config('pixelfed.open_registration'),
|
||||
'protocols' => [
|
||||
'activitypub'
|
||||
'activitypub',
|
||||
],
|
||||
'services' => [
|
||||
'inbound' => [],
|
||||
'outbound' => []
|
||||
'outbound' => [],
|
||||
],
|
||||
'software' => [
|
||||
'name' => 'pixelfed',
|
||||
'version' => config('pixelfed.version')
|
||||
'version' => config('pixelfed.version'),
|
||||
],
|
||||
'usage' => [
|
||||
'localPosts' => \App\Status::whereLocal(true)->whereHas('media')->count(),
|
||||
|
@ -105,15 +106,15 @@ class FederationController extends Controller
|
|||
'total' => \App\User::count(),
|
||||
'activeHalfyear' => \App\User::where('updated_at', '>', Carbon::now()->subMonths(6)->toDateTimeString())->count(),
|
||||
'activeMonth' => \App\User::where('updated_at', '>', Carbon::now()->subMonths(1)->toDateTimeString())->count(),
|
||||
]
|
||||
],
|
||||
'version' => '2.0'
|
||||
],
|
||||
'version' => '2.0',
|
||||
];
|
||||
});
|
||||
|
||||
return response()->json($res, 200, [], JSON_PRETTY_PRINT);
|
||||
}
|
||||
|
||||
|
||||
public function webfinger(Request $request)
|
||||
{
|
||||
$this->validate($request, ['resource'=>'required|string|min:3|max:255']);
|
||||
|
@ -125,8 +126,10 @@ class FederationController extends Controller
|
|||
$parsed = Nickname::normalizeProfileUrl($resource);
|
||||
$username = $parsed['username'];
|
||||
$user = Profile::whereUsername($username)->firstOrFail();
|
||||
|
||||
return (new Webfinger($user))->generate();
|
||||
});
|
||||
|
||||
return response()->json($webfinger, 200, [], JSON_PRETTY_PRINT);
|
||||
}
|
||||
|
||||
|
@ -139,8 +142,9 @@ class FederationController extends Controller
|
|||
$user = Profile::whereNull('remote_url')->whereUsername($username)->firstOrFail();
|
||||
$timeline = $user->statuses()->orderBy('created_at', 'desc')->paginate(10);
|
||||
$fractal = new Fractal\Manager();
|
||||
$resource = new Fractal\Resource\Item($user, new ProfileOutbox);
|
||||
$resource = new Fractal\Resource\Item($user, new ProfileOutbox());
|
||||
$res = $fractal->createData($resource)->toArray();
|
||||
|
||||
return response(json_encode($res['data']))->header('Content-Type', 'application/activity+json');
|
||||
}
|
||||
|
||||
|
@ -151,7 +155,7 @@ class FederationController extends Controller
|
|||
}
|
||||
$mimes = [
|
||||
'application/activity+json',
|
||||
'application/ld+json; profile="https://www.w3.org/ns/activitystreams"'
|
||||
'application/ld+json; profile="https://www.w3.org/ns/activitystreams"',
|
||||
];
|
||||
if (!in_array($request->header('Content-Type'), $mimes)) {
|
||||
abort(500, 'Invalid request');
|
||||
|
@ -159,5 +163,4 @@ class FederationController extends Controller
|
|||
$profile = Profile::whereUsername($username)->firstOrFail();
|
||||
InboxWorker::dispatch($request, $profile, $request->all());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -2,10 +2,11 @@
|
|||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Auth;
|
||||
use App\{Follower, Profile};
|
||||
use Illuminate\Http\Request;
|
||||
use App\Follower;
|
||||
use App\Jobs\FollowPipeline\FollowPipeline;
|
||||
use App\Profile;
|
||||
use Auth;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class FollowerController extends Controller
|
||||
{
|
||||
|
@ -26,7 +27,7 @@ class FollowerController extends Controller
|
|||
$isFollowing = Follower::whereProfileId($user->id)->whereFollowingId($target->id)->count();
|
||||
|
||||
if ($isFollowing == 0) {
|
||||
$follower = new Follower;
|
||||
$follower = new Follower();
|
||||
$follower->profile_id = $user->id;
|
||||
$follower->following_id = $target->id;
|
||||
$follower->save();
|
||||
|
@ -36,7 +37,6 @@ class FollowerController extends Controller
|
|||
$follower->delete();
|
||||
}
|
||||
|
||||
|
||||
return redirect()->back();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,8 +2,6 @@
|
|||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class HashtagController extends Controller
|
||||
{
|
||||
//
|
||||
|
|
|
@ -2,8 +2,6 @@
|
|||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class HomeController extends Controller
|
||||
{
|
||||
/**
|
||||
|
|
|
@ -2,10 +2,13 @@
|
|||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Auth, Cache, Hashids;
|
||||
use App\{Like, Profile, Status, User};
|
||||
use App\Jobs\LikePipeline\LikePipeline;
|
||||
use App\Like;
|
||||
use App\Status;
|
||||
use App\User;
|
||||
use Auth;
|
||||
use Cache;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class LikeController extends Controller
|
||||
{
|
||||
|
@ -30,7 +33,7 @@ class LikeController extends Controller
|
|||
$like->forceDelete();
|
||||
$count--;
|
||||
} else {
|
||||
$like = new Like;
|
||||
$like = new Like();
|
||||
$like->profile_id = $profile->id;
|
||||
$like->status_id = $status->id;
|
||||
$like->save();
|
||||
|
|
|
@ -2,8 +2,6 @@
|
|||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class MediaController extends Controller
|
||||
{
|
||||
//
|
||||
|
|
|
@ -2,8 +2,6 @@
|
|||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class NotificationController extends Controller
|
||||
{
|
||||
//
|
||||
|
|
|
@ -2,16 +2,13 @@
|
|||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Follower;
|
||||
use App\Profile;
|
||||
use App\Transformer\ActivityPub\ProfileTransformer;
|
||||
use App\User;
|
||||
use Auth;
|
||||
use Illuminate\Http\Request;
|
||||
use Auth, Cache;
|
||||
use App\{Follower, Profile, User};
|
||||
use League\Fractal;
|
||||
use App\Util\Lexer\Nickname;
|
||||
use App\Util\Webfinger\Webfinger;
|
||||
use App\Transformer\ActivityPub\{
|
||||
ProfileOutbox,
|
||||
ProfileTransformer
|
||||
};
|
||||
|
||||
class ProfileController extends Controller
|
||||
{
|
||||
|
@ -19,7 +16,7 @@ class ProfileController extends Controller
|
|||
{
|
||||
$user = Profile::whereUsername($username)->firstOrFail();
|
||||
if ($user->remote_url) {
|
||||
$settings = new \StdClass;
|
||||
$settings = new \StdClass();
|
||||
$settings->crawlable = false;
|
||||
} else {
|
||||
$settings = User::whereUsername($username)->firstOrFail()->settings;
|
||||
|
@ -80,8 +77,9 @@ class ProfileController extends Controller
|
|||
public function showActivityPub(Request $request, $user)
|
||||
{
|
||||
$fractal = new Fractal\Manager();
|
||||
$resource = new Fractal\Resource\Item($user, new ProfileTransformer);
|
||||
$resource = new Fractal\Resource\Item($user, new ProfileTransformer());
|
||||
$res = $fractal->createData($resource)->toArray();
|
||||
|
||||
return response(json_encode($res['data']))->header('Content-Type', 'application/activity+json');
|
||||
}
|
||||
|
||||
|
@ -89,6 +87,7 @@ class ProfileController extends Controller
|
|||
{
|
||||
$profile = Profile::whereUsername($user)->firstOrFail();
|
||||
$items = $profile->statuses()->orderBy('created_at', 'desc')->take(10)->get();
|
||||
|
||||
return response()->view('atom.user', compact('profile', 'items'))
|
||||
->header('Content-Type', 'application/atom+xml');
|
||||
}
|
||||
|
@ -102,6 +101,7 @@ class ProfileController extends Controller
|
|||
$is_following = ($owner == false && Auth::check()) ? $user->followedBy(Auth::user()->profile) : false;
|
||||
$followers = $profile->followers()->orderBy('created_at', 'desc')->simplePaginate(12);
|
||||
$is_admin = is_null($user->domain) ? $user->user->is_admin : false;
|
||||
|
||||
return view('profile.followers', compact('user', 'profile', 'followers', 'owner', 'is_following', 'is_admin'));
|
||||
}
|
||||
|
||||
|
@ -114,6 +114,7 @@ class ProfileController extends Controller
|
|||
$is_following = ($owner == false && Auth::check()) ? $user->followedBy(Auth::user()->profile) : false;
|
||||
$following = $profile->following()->orderBy('created_at', 'desc')->simplePaginate(12);
|
||||
$is_admin = is_null($user->domain) ? $user->user->is_admin : false;
|
||||
|
||||
return view('profile.following', compact('user', 'profile', 'following', 'owner', 'is_following', 'is_admin'));
|
||||
}
|
||||
|
||||
|
@ -129,6 +130,7 @@ class ProfileController extends Controller
|
|||
$timeline = $user->bookmarks()->withCount(['likes', 'comments'])->orderBy('created_at', 'desc')->simplePaginate(10);
|
||||
$is_following = ($owner == false && Auth::check()) ? $user->followedBy(Auth::user()->profile) : false;
|
||||
$is_admin = is_null($user->domain) ? $user->user->is_admin : false;
|
||||
|
||||
return view('profile.show', compact('user', 'settings', 'owner', 'following', 'timeline', 'is_following', 'is_admin'));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,9 +2,12 @@
|
|||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Profile;
|
||||
use App\Report;
|
||||
use App\Status;
|
||||
use App\User;
|
||||
use Auth;
|
||||
use Illuminate\Http\Request;
|
||||
use App\{Avatar, Profile, Report, Status, User};
|
||||
|
||||
class ReportController extends Controller
|
||||
{
|
||||
|
@ -19,8 +22,9 @@ class ReportController extends Controller
|
|||
{
|
||||
$this->validate($request, [
|
||||
'type' => 'required|alpha_dash',
|
||||
'id' => 'required|integer|min:1'
|
||||
'id' => 'required|integer|min:1',
|
||||
]);
|
||||
|
||||
return view('report.form');
|
||||
}
|
||||
|
||||
|
@ -85,7 +89,7 @@ class ReportController extends Controller
|
|||
'report' => 'required|alpha_dash',
|
||||
'type' => 'required|alpha_dash',
|
||||
'id' => 'required|integer|min:1',
|
||||
'msg' => 'nullable|string|max:150'
|
||||
'msg' => 'nullable|string|max:150',
|
||||
]);
|
||||
|
||||
$profile = Auth::user()->profile;
|
||||
|
@ -123,7 +127,7 @@ class ReportController extends Controller
|
|||
return redirect('/timeline')->with('error', 'You cannot report your own content!');
|
||||
}
|
||||
|
||||
$report = new Report;
|
||||
$report = new Report();
|
||||
$report->profile_id = $profile->id;
|
||||
$report->user_id = Auth::id();
|
||||
$report->object_id = $object->id;
|
||||
|
@ -135,5 +139,4 @@ class ReportController extends Controller
|
|||
|
||||
return redirect('/timeline')->with('status', 'Report successfully sent!');
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -2,7 +2,8 @@
|
|||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\{Hashtag, Profile};
|
||||
use App\Hashtag;
|
||||
use App\Profile;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
|
||||
|
@ -19,7 +20,7 @@ class SearchController extends Controller
|
|||
'type' => 'hashtag',
|
||||
'value' => $item->name,
|
||||
'tokens' => explode('-', $item->name),
|
||||
'name' => null
|
||||
'name' => null,
|
||||
];
|
||||
});
|
||||
$res = Profile::where('username', 'like', '%'.$tag.'%')->get();
|
||||
|
@ -30,10 +31,11 @@ class SearchController extends Controller
|
|||
'type' => 'profile',
|
||||
'value' => $item->username,
|
||||
'tokens' => [$item->username],
|
||||
'name' => $item->name
|
||||
'name' => $item->name,
|
||||
];
|
||||
});
|
||||
$tags = $tags->push($profiles[0]);
|
||||
|
||||
return $tags;
|
||||
});
|
||||
|
||||
|
|
|
@ -2,10 +2,15 @@
|
|||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use App\{AccountLog, EmailVerification, Media, Profile, User};
|
||||
use Auth, DB;
|
||||
use App\AccountLog;
|
||||
use App\EmailVerification;
|
||||
use App\Media;
|
||||
use App\Profile;
|
||||
use App\User;
|
||||
use App\Util\Lexer\PrettyNumber;
|
||||
use Auth;
|
||||
use DB;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class SettingsController extends Controller
|
||||
{
|
||||
|
@ -24,6 +29,7 @@ class SettingsController extends Controller
|
|||
$storage['percentUsed'] = ceil($storage['used'] / $storage['limit'] * 100);
|
||||
$storage['limitPretty'] = PrettyNumber::size($storage['limit']);
|
||||
$storage['usedPretty'] = PrettyNumber::size($storage['used']);
|
||||
|
||||
return view('settings.home', compact('storage'));
|
||||
}
|
||||
|
||||
|
@ -33,7 +39,7 @@ class SettingsController extends Controller
|
|||
'name' => 'required|string|max:'.config('pixelfed.max_name_length'),
|
||||
'bio' => 'nullable|string|max:'.config('pixelfed.max_bio_length'),
|
||||
'website' => 'nullable|url',
|
||||
'email' => 'nullable|email'
|
||||
'email' => 'nullable|email',
|
||||
]);
|
||||
|
||||
$changes = false;
|
||||
|
@ -79,6 +85,7 @@ class SettingsController extends Controller
|
|||
if ($changes === true) {
|
||||
$user->save();
|
||||
$profile->save();
|
||||
|
||||
return redirect('/settings/home')->with('status', 'Profile successfully updated!');
|
||||
}
|
||||
|
||||
|
@ -110,6 +117,7 @@ class SettingsController extends Controller
|
|||
|
||||
return redirect('/settings/home')->with('status', 'Password successfully updated!');
|
||||
}
|
||||
|
||||
return redirect('/settings/home')->with('error', 'There was an error with your request!');
|
||||
}
|
||||
|
||||
|
@ -126,6 +134,7 @@ class SettingsController extends Controller
|
|||
public function accessibility()
|
||||
{
|
||||
$settings = Auth::user()->settings;
|
||||
|
||||
return view('settings.accessibility', compact('settings'));
|
||||
}
|
||||
|
||||
|
@ -137,7 +146,7 @@ class SettingsController extends Controller
|
|||
'reduce_motion',
|
||||
'optimize_screen_reader',
|
||||
'high_contrast_mode',
|
||||
'video_autoplay'
|
||||
'video_autoplay',
|
||||
];
|
||||
foreach ($fields as $field) {
|
||||
$form = $request->input($field);
|
||||
|
@ -148,6 +157,7 @@ class SettingsController extends Controller
|
|||
}
|
||||
$settings->save();
|
||||
}
|
||||
|
||||
return redirect(route('settings.accessibility'))->with('status', 'Settings successfully updated!');
|
||||
}
|
||||
|
||||
|
@ -161,6 +171,7 @@ class SettingsController extends Controller
|
|||
$settings = Auth::user()->settings;
|
||||
$is_private = Auth::user()->profile->is_private;
|
||||
$settings['is_private'] = (bool) $is_private;
|
||||
|
||||
return view('settings.privacy', compact('settings'));
|
||||
}
|
||||
|
||||
|
@ -172,7 +183,7 @@ class SettingsController extends Controller
|
|||
'is_private',
|
||||
'crawlable',
|
||||
'show_profile_follower_count',
|
||||
'show_profile_following_count'
|
||||
'show_profile_following_count',
|
||||
];
|
||||
foreach ($fields as $field) {
|
||||
$form = $request->input($field);
|
||||
|
@ -201,6 +212,7 @@ class SettingsController extends Controller
|
|||
}
|
||||
$settings->save();
|
||||
}
|
||||
|
||||
return redirect(route('settings.privacy'))->with('status', 'Settings successfully updated!');
|
||||
}
|
||||
|
||||
|
@ -214,6 +226,7 @@ class SettingsController extends Controller
|
|||
->orderBy('created_at', 'desc')
|
||||
->limit(50)
|
||||
->get();
|
||||
|
||||
return view('settings.security', compact('sessions', 'activity'));
|
||||
}
|
||||
|
||||
|
|
|
@ -2,14 +2,18 @@
|
|||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App, Auth, Cache;
|
||||
use Illuminate\Http\Request;
|
||||
use App\{Follower, Profile, Status, User};
|
||||
use App;
|
||||
use App\Follower;
|
||||
use App\Profile;
|
||||
use App\Status;
|
||||
use App\User;
|
||||
use App\Util\Lexer\PrettyNumber;
|
||||
use Auth;
|
||||
use Cache;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class SiteController extends Controller
|
||||
{
|
||||
|
||||
public function home()
|
||||
{
|
||||
if (Auth::check()) {
|
||||
|
@ -35,6 +39,7 @@ class SiteController extends Controller
|
|||
->withCount(['comments', 'likes', 'shares'])
|
||||
->simplePaginate(20);
|
||||
$type = 'personal';
|
||||
|
||||
return view('timeline.template', compact('timeline', 'type'));
|
||||
}
|
||||
|
||||
|
@ -44,6 +49,7 @@ class SiteController extends Controller
|
|||
return redirect()->back();
|
||||
}
|
||||
App::setLocale($locale);
|
||||
|
||||
return redirect()->back();
|
||||
}
|
||||
|
||||
|
@ -58,8 +64,10 @@ class SiteController extends Controller
|
|||
$userCount = PrettyNumber::convert(User::count());
|
||||
$remoteCount = PrettyNumber::convert(Profile::whereNotNull('remote_url')->count());
|
||||
$adminContact = User::whereIsAdmin(true)->first();
|
||||
|
||||
return view('site.about')->with(compact('statusCount', 'userCount', 'remoteCount', 'adminContact'))->render();
|
||||
});
|
||||
|
||||
return $res;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,14 +2,18 @@
|
|||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Auth, Cache;
|
||||
use League\Fractal;
|
||||
use Illuminate\Http\Request;
|
||||
use Vinkla\Hashids\Facades\Hashids;
|
||||
use App\{Media, Profile, Status, User};
|
||||
use App\Jobs\ImageOptimizePipeline\ImageOptimize;
|
||||
use App\Jobs\StatusPipeline\NewStatusPipeline;
|
||||
use App\Jobs\StatusPipeline\StatusDelete;
|
||||
use App\Media;
|
||||
use App\Profile;
|
||||
use App\Status;
|
||||
use App\Transformer\ActivityPub\StatusTransformer;
|
||||
use App\Jobs\StatusPipeline\{NewStatusPipeline, StatusDelete};
|
||||
use App\User;
|
||||
use Auth;
|
||||
use Cache;
|
||||
use Illuminate\Http\Request;
|
||||
use League\Fractal;
|
||||
|
||||
class StatusController extends Controller
|
||||
{
|
||||
|
@ -45,14 +49,17 @@ class StatusController extends Controller
|
|||
if ($status->viewType() == 'video') {
|
||||
$template = 'status.show.video';
|
||||
}
|
||||
|
||||
return $template;
|
||||
});
|
||||
|
||||
return $template;
|
||||
}
|
||||
|
||||
public function compose()
|
||||
{
|
||||
$this->authCheck();
|
||||
|
||||
return view('status.compose');
|
||||
}
|
||||
|
||||
|
@ -83,7 +90,7 @@ class StatusController extends Controller
|
|||
$userHash = hash('sha1', $user->id.(string) $user->created_at);
|
||||
$profile = $user->profile;
|
||||
|
||||
$status = new Status;
|
||||
$status = new Status();
|
||||
$status->profile_id = $profile->id;
|
||||
$status->caption = strip_tags($request->caption);
|
||||
$status->is_nsfw = $cw;
|
||||
|
@ -96,7 +103,7 @@ class StatusController extends Controller
|
|||
$storagePath = "public/m/{$monthHash}/{$userHash}";
|
||||
$path = $v->store($storagePath);
|
||||
$hash = \hash_file('sha256', $v);
|
||||
$media = new Media;
|
||||
$media = new Media();
|
||||
$media->status_id = $status->id;
|
||||
$media->profile_id = $profile->id;
|
||||
$media->user_id = $user->id;
|
||||
|
@ -127,7 +134,7 @@ class StatusController extends Controller
|
|||
|
||||
$this->validate($request, [
|
||||
'type' => 'required|string',
|
||||
'item' => 'required|integer|min:1'
|
||||
'item' => 'required|integer|min:1',
|
||||
]);
|
||||
|
||||
$status = Status::findOrFail($request->input('item'));
|
||||
|
@ -162,7 +169,7 @@ class StatusController extends Controller
|
|||
$count--;
|
||||
}
|
||||
} else {
|
||||
$share = new Status;
|
||||
$share = new Status();
|
||||
$share->profile_id = $profile->id;
|
||||
$share->reblog_of_id = $status->id;
|
||||
$share->save();
|
||||
|
@ -181,8 +188,9 @@ class StatusController extends Controller
|
|||
public function showActivityPub(Request $request, $status)
|
||||
{
|
||||
$fractal = new Fractal\Manager();
|
||||
$resource = new Fractal\Resource\Item($status, new StatusTransformer);
|
||||
$resource = new Fractal\Resource\Item($status, new StatusTransformer());
|
||||
$res = $fractal->createData($resource)->toArray();
|
||||
|
||||
return response(json_encode($res['data']))->header('Content-Type', 'application/activity+json');
|
||||
}
|
||||
|
||||
|
@ -193,10 +201,10 @@ class StatusController extends Controller
|
|||
$status = Status::whereProfileId($user->id)
|
||||
->with(['media'])
|
||||
->findOrFail($id);
|
||||
|
||||
return view('status.edit', compact('user', 'status'));
|
||||
}
|
||||
|
||||
|
||||
public function editStore(Request $request, $username, $id)
|
||||
{
|
||||
$this->authCheck();
|
||||
|
@ -208,7 +216,7 @@ class StatusController extends Controller
|
|||
$this->validate($request, [
|
||||
'id' => 'required|integer|min:1',
|
||||
'caption' => 'nullable',
|
||||
'filter' => 'nullable|alpha_dash|max:30'
|
||||
'filter' => 'nullable|alpha_dash|max:30',
|
||||
]);
|
||||
|
||||
$id = $request->input('id');
|
||||
|
@ -234,13 +242,13 @@ class StatusController extends Controller
|
|||
if ($changed === true) {
|
||||
$media->save();
|
||||
}
|
||||
|
||||
return response()->json([], 200);
|
||||
}
|
||||
|
||||
protected function authCheck()
|
||||
{
|
||||
if(Auth::check() == false)
|
||||
{
|
||||
if (Auth::check() == false) {
|
||||
abort(403);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,10 +2,6 @@
|
|||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use App\Profile;
|
||||
|
||||
class StoryController extends Controller
|
||||
{
|
||||
|
||||
}
|
|
@ -2,9 +2,12 @@
|
|||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use App\Follower;
|
||||
use App\Profile;
|
||||
use App\Status;
|
||||
use App\User;
|
||||
use App\UserFilter;
|
||||
use Auth;
|
||||
use App\{Follower, Profile, Status, User, UserFilter};
|
||||
|
||||
class TimelineController extends Controller
|
||||
{
|
||||
|
@ -29,6 +32,7 @@ class TimelineController extends Controller
|
|||
->withCount(['comments', 'likes'])
|
||||
->simplePaginate(20);
|
||||
$type = 'personal';
|
||||
|
||||
return view('timeline.template', compact('timeline', 'type'));
|
||||
}
|
||||
|
||||
|
@ -52,7 +56,7 @@ class TimelineController extends Controller
|
|||
->orderBy('id', 'desc')
|
||||
->simplePaginate(20);
|
||||
$type = 'local';
|
||||
|
||||
return view('timeline.template', compact('timeline', 'type'));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -2,7 +2,8 @@
|
|||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Auth, Closure;
|
||||
use Auth;
|
||||
use Closure;
|
||||
|
||||
class Admin
|
||||
{
|
||||
|
@ -11,6 +12,7 @@ class Admin
|
|||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Closure $next
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle($request, Closure $next)
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Auth, Closure;
|
||||
use Closure;
|
||||
|
||||
class EmailVerificationCheck
|
||||
{
|
||||
|
@ -11,6 +11,7 @@ class EmailVerificationCheck
|
|||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Closure $next
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle($request, Closure $next)
|
||||
|
@ -22,6 +23,7 @@ class EmailVerificationCheck
|
|||
) {
|
||||
return redirect('/i/verify-email');
|
||||
}
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@ class RedirectIfAuthenticated
|
|||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Closure $next
|
||||
* @param string|null $guard
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle($request, Closure $next, $guard = null)
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Fideloper\Proxy\TrustProxies as Middleware;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class TrustProxies extends Middleware
|
||||
{
|
||||
|
|
|
@ -2,14 +2,15 @@
|
|||
|
||||
namespace App\Jobs\AvatarPipeline;
|
||||
|
||||
use \Carbon\Carbon;
|
||||
use Image as Intervention;
|
||||
use App\{Avatar, Profile};
|
||||
use App\Avatar;
|
||||
use App\Profile;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Foundation\Bus\Dispatchable;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Image as Intervention;
|
||||
|
||||
class AvatarOptimize implements ShouldQueue
|
||||
{
|
||||
|
@ -54,7 +55,6 @@ class AvatarOptimize implements ShouldQueue
|
|||
$avatar->save();
|
||||
$this->deleteOldAvatar($avatar->media_path, $this->current);
|
||||
} catch (Exception $e) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2,23 +2,24 @@
|
|||
|
||||
namespace App\Jobs\AvatarPipeline;
|
||||
|
||||
use App\{Avatar, Profile};
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Foundation\Bus\Dispatchable;
|
||||
use Illuminate\Support\Str;
|
||||
use Bitverse\Identicon\Identicon;
|
||||
use App\Avatar;
|
||||
use App\Profile;
|
||||
use App\Util\Identicon\Preprocessor\HashPreprocessor;
|
||||
use Bitverse\Identicon\Color\Color;
|
||||
use Bitverse\Identicon\Generator\RingsGenerator;
|
||||
use App\Util\Identicon\Preprocessor\HashPreprocessor;
|
||||
use Bitverse\Identicon\Identicon;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Foundation\Bus\Dispatchable;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
class CreateAvatar implements ShouldQueue
|
||||
{
|
||||
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
||||
|
||||
protected $profile;
|
||||
|
||||
/**
|
||||
* Create a new job instance.
|
||||
*
|
||||
|
@ -48,7 +49,6 @@ class CreateAvatar implements ShouldQueue
|
|||
$icon = $identicon->getIcon($hash);
|
||||
|
||||
try {
|
||||
|
||||
$baseDir = storage_path('app/public/avatars');
|
||||
if (!is_dir($baseDir)) {
|
||||
mkdir($baseDir);
|
||||
|
@ -94,16 +94,14 @@ class CreateAvatar implements ShouldQueue
|
|||
$basePath = storage_path('app/'.$path);
|
||||
file_put_contents($basePath, $icon);
|
||||
} catch (Exception $e) {
|
||||
|
||||
}
|
||||
|
||||
$avatar = new Avatar;
|
||||
$avatar = new Avatar();
|
||||
$avatar->profile_id = $profile->id;
|
||||
$avatar->media_path = $path;
|
||||
$avatar->thumb_path = $path;
|
||||
$avatar->change_count = 0;
|
||||
$avatar->last_processed_at = \Carbon\Carbon::now();
|
||||
$avatar->save();
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,14 +2,16 @@
|
|||
|
||||
namespace App\Jobs\CommentPipeline;
|
||||
|
||||
use Cache, Log, Redis;
|
||||
use App\{Like, Notification, Status};
|
||||
use App\Util\Lexer\Hashtag as HashtagLexer;
|
||||
use App\Notification;
|
||||
use App\Status;
|
||||
use Cache;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Foundation\Bus\Dispatchable;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Log;
|
||||
use Redis;
|
||||
|
||||
class CommentPipeline implements ShouldQueue
|
||||
{
|
||||
|
@ -47,8 +49,7 @@ class CommentPipeline implements ShouldQueue
|
|||
}
|
||||
|
||||
try {
|
||||
|
||||
$notification = new Notification;
|
||||
$notification = new Notification();
|
||||
$notification->profile_id = $target->id;
|
||||
$notification->actor_id = $actor->id;
|
||||
$notification->action = 'comment';
|
||||
|
@ -64,10 +65,8 @@ class CommentPipeline implements ShouldQueue
|
|||
|
||||
$nkey = config('cache.prefix').':user.'.$target->id.'.notifications';
|
||||
$redis->lpush($nkey, $notification->id);
|
||||
|
||||
} catch (Exception $e) {
|
||||
Log::error($e);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,14 +2,15 @@
|
|||
|
||||
namespace App\Jobs\FollowPipeline;
|
||||
|
||||
use Cache, Log, Redis;
|
||||
use App\{Like, Notification};
|
||||
use App\Notification;
|
||||
use Cache;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Foundation\Bus\Dispatchable;
|
||||
use App\Jobs\FollowPipeline\FollowDiscover;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Log;
|
||||
use Redis;
|
||||
|
||||
class FollowPipeline implements ShouldQueue
|
||||
{
|
||||
|
@ -39,8 +40,7 @@ class FollowPipeline implements ShouldQueue
|
|||
$target = $follower->target;
|
||||
|
||||
try {
|
||||
|
||||
$notification = new Notification;
|
||||
$notification = new Notification();
|
||||
$notification->profile_id = $target->id;
|
||||
$notification->actor_id = $actor->id;
|
||||
$notification->action = 'follow';
|
||||
|
@ -56,7 +56,6 @@ class FollowPipeline implements ShouldQueue
|
|||
|
||||
$nkey = config('cache.prefix').':user.'.$target->id.'.notifications';
|
||||
$redis->lpush($nkey, $notification->id);
|
||||
|
||||
} catch (Exception $e) {
|
||||
Log::error($e);
|
||||
}
|
||||
|
|
|
@ -2,14 +2,12 @@
|
|||
|
||||
namespace App\Jobs\ImageOptimizePipeline;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use ImageOptimizer;
|
||||
use App\{Media, Status};
|
||||
use App\Media;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Foundation\Bus\Dispatchable;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
class ImageOptimize implements ShouldQueue
|
||||
{
|
||||
|
|
|
@ -2,15 +2,13 @@
|
|||
|
||||
namespace App\Jobs\ImageOptimizePipeline;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use ImageOptimizer;
|
||||
use App\{Media, Status};
|
||||
use App\Media;
|
||||
use App\Util\Media\Image;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Foundation\Bus\Dispatchable;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
class ImageResize implements ShouldQueue
|
||||
{
|
||||
|
@ -42,10 +40,9 @@ class ImageResize implements ShouldQueue
|
|||
}
|
||||
|
||||
try {
|
||||
$img = new Image;
|
||||
$img = new Image();
|
||||
$img->resizeImage($media);
|
||||
} catch (Exception $e) {
|
||||
|
||||
}
|
||||
|
||||
ImageThumbnail::dispatch($media);
|
||||
|
|
|
@ -2,14 +2,14 @@
|
|||
|
||||
namespace App\Jobs\ImageOptimizePipeline;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use App\{Media, Status};
|
||||
use App\Media;
|
||||
use App\Util\Media\Image;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Foundation\Bus\Dispatchable;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
class ImageThumbnail implements ShouldQueue
|
||||
{
|
||||
|
@ -41,10 +41,9 @@ class ImageThumbnail implements ShouldQueue
|
|||
}
|
||||
|
||||
try {
|
||||
$img = new Image;
|
||||
$img = new Image();
|
||||
$img->resizeThumbnail($media);
|
||||
} catch (Exception $e) {
|
||||
|
||||
}
|
||||
|
||||
$media->processed_at = Carbon::now();
|
||||
|
|
|
@ -2,13 +2,13 @@
|
|||
|
||||
namespace App\Jobs\ImageOptimizePipeline;
|
||||
|
||||
use ImageOptimizer;
|
||||
use App\{Media, Status};
|
||||
use App\Media;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Foundation\Bus\Dispatchable;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use ImageOptimizer;
|
||||
|
||||
class ImageUpdate implements ShouldQueue
|
||||
{
|
||||
|
@ -19,7 +19,7 @@ class ImageUpdate implements ShouldQueue
|
|||
protected $protectedMimes = [
|
||||
'image/gif',
|
||||
'image/bmp',
|
||||
'video/mp4'
|
||||
'video/mp4',
|
||||
];
|
||||
|
||||
/**
|
||||
|
@ -42,9 +42,9 @@ class ImageUpdate implements ShouldQueue
|
|||
$media = $this->media;
|
||||
$path = storage_path('app/'.$media->media_path);
|
||||
$thumb = storage_path('app/'.$media->thumbnail_path);
|
||||
|
||||
try {
|
||||
if(!in_array($media->mime, $this->protectedMimes))
|
||||
{
|
||||
if (!in_array($media->mime, $this->protectedMimes)) {
|
||||
ImageOptimizer::optimize($thumb);
|
||||
ImageOptimizer::optimize($path);
|
||||
}
|
||||
|
|
|
@ -5,10 +5,10 @@ namespace App\Jobs\InboxPipeline;
|
|||
use App\Profile;
|
||||
use App\Util\ActivityPub\Inbox;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Foundation\Bus\Dispatchable;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
class InboxWorker implements ShouldQueue
|
||||
{
|
||||
|
@ -39,5 +39,4 @@ class InboxWorker implements ShouldQueue
|
|||
{
|
||||
(new Inbox($this->request, $this->profile, $this->payload))->handle();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -2,13 +2,12 @@
|
|||
|
||||
namespace App\Jobs\InboxPipeline;
|
||||
|
||||
use App\Profile;
|
||||
use App\Util\ActivityPub\Inbox;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Foundation\Bus\Dispatchable;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
class SharedInboxWorker implements ShouldQueue
|
||||
{
|
||||
|
|
|
@ -2,19 +2,23 @@
|
|||
|
||||
namespace App\Jobs\LikePipeline;
|
||||
|
||||
use Cache, Log, Redis;
|
||||
use App\{Like, Notification};
|
||||
use App\Like;
|
||||
use App\Notification;
|
||||
use Cache;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Foundation\Bus\Dispatchable;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Log;
|
||||
use Redis;
|
||||
|
||||
class LikePipeline implements ShouldQueue
|
||||
{
|
||||
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
||||
|
||||
protected $like;
|
||||
|
||||
/**
|
||||
* Create a new job instance.
|
||||
*
|
||||
|
@ -54,8 +58,7 @@ class LikePipeline implements ShouldQueue
|
|||
}
|
||||
|
||||
try {
|
||||
|
||||
$notification = new Notification;
|
||||
$notification = new Notification();
|
||||
$notification->profile_id = $status->profile_id;
|
||||
$notification->actor_id = $actor->id;
|
||||
$notification->action = 'like';
|
||||
|
@ -70,7 +73,6 @@ class LikePipeline implements ShouldQueue
|
|||
$redis = Redis::connection();
|
||||
$key = config('cache.prefix').':user.'.$status->profile_id.'.notifications';
|
||||
$redis->lpush($key, $notification->id);
|
||||
|
||||
} catch (Exception $e) {
|
||||
Log::error($e);
|
||||
}
|
||||
|
|
|
@ -2,13 +2,14 @@
|
|||
|
||||
namespace App\Jobs\MentionPipeline;
|
||||
|
||||
use Cache, Log, Redis;
|
||||
use App\{Mention, Notification, Profile, Status};
|
||||
use App\Mention;
|
||||
use App\Notification;
|
||||
use App\Status;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Foundation\Bus\Dispatchable;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
class MentionPipeline implements ShouldQueue
|
||||
{
|
||||
|
@ -35,7 +36,6 @@ class MentionPipeline implements ShouldQueue
|
|||
*/
|
||||
public function handle()
|
||||
{
|
||||
|
||||
$status = $this->status;
|
||||
$mention = $this->mention;
|
||||
$actor = $this->status->profile;
|
||||
|
@ -53,8 +53,7 @@ class MentionPipeline implements ShouldQueue
|
|||
}
|
||||
|
||||
try {
|
||||
|
||||
$notification = new Notification;
|
||||
$notification = new Notification();
|
||||
$notification->profile_id = $target;
|
||||
$notification->actor_id = $actor->id;
|
||||
$notification->action = 'mention';
|
||||
|
@ -63,10 +62,7 @@ class MentionPipeline implements ShouldQueue
|
|||
$notification->item_id = $status->id;
|
||||
$notification->item_type = "App\Status";
|
||||
$notification->save();
|
||||
|
||||
} catch (Exception $e) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,18 +2,20 @@
|
|||
|
||||
namespace App\Jobs\RemoteFollowPipeline;
|
||||
|
||||
use Zttp\Zttp;
|
||||
use Log, Storage;
|
||||
use App\Jobs\ImageOptimizePipeline\ImageThumbnail;
|
||||
use App\Jobs\StatusPipeline\NewStatusPipeline;
|
||||
use App\Media;
|
||||
use App\Status;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Http\File;
|
||||
use App\{Media, Profile, Status};
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Foundation\Bus\Dispatchable;
|
||||
use App\Jobs\StatusPipeline\NewStatusPipeline;
|
||||
use App\Jobs\ImageOptimizePipeline\ImageThumbnail;
|
||||
use Illuminate\Http\File;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Log;
|
||||
use Storage;
|
||||
use Zttp\Zttp;
|
||||
|
||||
class RemoteFollowImportRecent implements ShouldQueue
|
||||
{
|
||||
|
@ -42,7 +44,7 @@ class RemoteFollowImportRecent implements ShouldQueue
|
|||
'image/jpg',
|
||||
'image/jpeg',
|
||||
'image/png',
|
||||
'image/gif'
|
||||
'image/gif',
|
||||
];
|
||||
}
|
||||
|
||||
|
@ -62,7 +64,7 @@ class RemoteFollowImportRecent implements ShouldQueue
|
|||
$url = ($url == false) ? $this->actor['outbox'] : $url;
|
||||
|
||||
$response = Zttp::withHeaders([
|
||||
'User-Agent' => 'PixelFedBot v0.1 - https://pixelfed.org'
|
||||
'User-Agent' => 'PixelFedBot v0.1 - https://pixelfed.org',
|
||||
])->get($url);
|
||||
|
||||
$this->outbox = $response->json();
|
||||
|
@ -76,6 +78,7 @@ class RemoteFollowImportRecent implements ShouldQueue
|
|||
if (isset($outbox['totalItems']) && $outbox['totalItems'] < 1) {
|
||||
// Skip remote fetch, not enough posts
|
||||
Log::info('not enough items');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -102,6 +105,7 @@ class RemoteFollowImportRecent implements ShouldQueue
|
|||
// Mastodon detected
|
||||
Log::info('Mastodon detected...');
|
||||
$this->nextUrl = $outbox['first'];
|
||||
|
||||
return $this->fetchOutbox($this->nextUrl);
|
||||
} else {
|
||||
// Pleroma detected.
|
||||
|
@ -110,7 +114,6 @@ class RemoteFollowImportRecent implements ShouldQueue
|
|||
$orderedItems = isset($outbox['orderedItems']) ? $outbox['orderedItems'] : $outbox['first']['orderedItems'];
|
||||
}
|
||||
|
||||
|
||||
foreach ($orderedItems as $item) {
|
||||
Log::info('Parsing items...');
|
||||
$parsed = $this->parseObject($item);
|
||||
|
@ -125,7 +128,6 @@ class RemoteFollowImportRecent implements ShouldQueue
|
|||
$this->mediaCount++;
|
||||
$this->fetchOutbox($this->nextUrl);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public function parseObject($parsed)
|
||||
|
@ -165,7 +167,7 @@ class RemoteFollowImportRecent implements ShouldQueue
|
|||
return true;
|
||||
}
|
||||
|
||||
$status = new Status;
|
||||
$status = new Status();
|
||||
$status->profile_id = $profile->id;
|
||||
$status->url = $activity['id'];
|
||||
$status->local = false;
|
||||
|
@ -202,6 +204,7 @@ class RemoteFollowImportRecent implements ShouldQueue
|
|||
$monthHash = hash('sha1', date('Y').date('m'));
|
||||
$userHash = hash('sha1', $user->id.(string) $user->created_at);
|
||||
$storagePath = "public/m/{$monthHash}/{$userHash}";
|
||||
|
||||
try {
|
||||
$info = pathinfo($url);
|
||||
$img = file_get_contents($url);
|
||||
|
@ -209,7 +212,7 @@ class RemoteFollowImportRecent implements ShouldQueue
|
|||
file_put_contents($file, $img);
|
||||
$path = Storage::putFile($storagePath, new File($file), 'public');
|
||||
|
||||
$media = new Media;
|
||||
$media = new Media();
|
||||
$media->status_id = $status->id;
|
||||
$media->profile_id = $status->profile_id;
|
||||
$media->user_id = null;
|
||||
|
@ -225,5 +228,4 @@ class RemoteFollowImportRecent implements ShouldQueue
|
|||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -2,18 +2,17 @@
|
|||
|
||||
namespace App\Jobs\RemoteFollowPipeline;
|
||||
|
||||
use Zttp\Zttp;
|
||||
use App\Jobs\AvatarPipeline\CreateAvatar;
|
||||
use App\{Profile};
|
||||
use GuzzleHttp\Client;
|
||||
use HttpSignatures\Context;
|
||||
use HttpSignatures\GuzzleHttpSignatures;
|
||||
use App\Jobs\RemoteFollowPipeline\RemoteFollowImportRecent;
|
||||
use App\Jobs\AvatarPipeline\CreateAvatar;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Foundation\Bus\Dispatchable;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Zttp\Zttp;
|
||||
|
||||
class RemoteFollowPipeline implements ShouldQueue
|
||||
{
|
||||
|
@ -49,6 +48,7 @@ class RemoteFollowPipeline implements ShouldQueue
|
|||
}
|
||||
|
||||
$this->discover($url);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -64,7 +64,7 @@ class RemoteFollowPipeline implements ShouldQueue
|
|||
$client = new Client(['handler' => $handlerStack]);
|
||||
$response = Zttp::withHeaders([
|
||||
'Accept' => 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"',
|
||||
'User-Agent' => 'PixelFedBot v0.1 - https://pixelfed.org'
|
||||
'User-Agent' => 'PixelFedBot v0.1 - https://pixelfed.org',
|
||||
])->get($url);
|
||||
$this->response = $response->json();
|
||||
|
||||
|
@ -78,7 +78,7 @@ class RemoteFollowPipeline implements ShouldQueue
|
|||
$username = $res['preferredUsername'];
|
||||
$remoteUsername = "@{$username}@{$domain}";
|
||||
|
||||
$profile = new Profile;
|
||||
$profile = new Profile();
|
||||
$profile->user_id = null;
|
||||
$profile->domain = $domain;
|
||||
$profile->username = $remoteUsername;
|
||||
|
@ -99,7 +99,7 @@ class RemoteFollowPipeline implements ShouldQueue
|
|||
|
||||
$activity = Zttp::withHeaders(['Content-Type' => 'application/activity+json'])->post($url, [
|
||||
'type' => 'Follow',
|
||||
'object' => $this->follower->url()
|
||||
'object' => $this->follower->url(),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,14 +2,14 @@
|
|||
|
||||
namespace App\Jobs\StatusPipeline;
|
||||
|
||||
use Cache, Redis;
|
||||
use App\{Media, Status};
|
||||
use App\Jobs\ImageOptimizePipeline\ImageOptimize;
|
||||
use App\Status;
|
||||
use Cache;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Foundation\Bus\Dispatchable;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Redis;
|
||||
|
||||
class NewStatusPipeline implements ShouldQueue
|
||||
{
|
||||
|
|
|
@ -2,18 +2,19 @@
|
|||
|
||||
namespace App\Jobs\StatusPipeline;
|
||||
|
||||
use App\{Media, Status};
|
||||
use App\Status;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Foundation\Bus\Dispatchable;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
class StatusActivityPubDeliver implements ShouldQueue
|
||||
{
|
||||
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
||||
|
||||
protected $status;
|
||||
|
||||
/**
|
||||
* Create a new job instance.
|
||||
*
|
||||
|
|
|
@ -2,12 +2,14 @@
|
|||
|
||||
namespace App\Jobs\StatusPipeline;
|
||||
|
||||
use App\{Media, Notification, StatusHashtag, Status};
|
||||
use App\Notification;
|
||||
use App\Status;
|
||||
use App\StatusHashtag;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Foundation\Bus\Dispatchable;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
class StatusDelete implements ShouldQueue
|
||||
{
|
||||
|
@ -55,7 +57,6 @@ class StatusDelete implements ShouldQueue
|
|||
}
|
||||
$media->delete();
|
||||
} catch (Exception $e) {
|
||||
|
||||
}
|
||||
}
|
||||
$comments = Status::where('in_reply_to_id', $status->id)->get();
|
||||
|
|
|
@ -2,23 +2,20 @@
|
|||
|
||||
namespace App\Jobs\StatusPipeline;
|
||||
|
||||
use DB, Cache;
|
||||
use App\{
|
||||
Hashtag,
|
||||
Media,
|
||||
Mention,
|
||||
Profile,
|
||||
Status,
|
||||
StatusHashtag
|
||||
};
|
||||
use App\Util\Lexer\Hashtag as HashtagLexer;
|
||||
use App\Util\Lexer\{Autolink, Extractor};
|
||||
use App\Hashtag;
|
||||
use App\Jobs\MentionPipeline\MentionPipeline;
|
||||
use App\Mention;
|
||||
use App\Profile;
|
||||
use App\Status;
|
||||
use App\StatusHashtag;
|
||||
use App\Util\Lexer\Autolink;
|
||||
use App\Util\Lexer\Extractor;
|
||||
use DB;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Foundation\Bus\Dispatchable;
|
||||
use App\Jobs\MentionPipeline\MentionPipeline;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
class StatusEntityLexer implements ShouldQueue
|
||||
{
|
||||
|
@ -109,7 +106,7 @@ class StatusEntityLexer implements ShouldQueue
|
|||
}
|
||||
|
||||
DB::transaction(function () use ($status, $mentioned) {
|
||||
$m = new Mention;
|
||||
$m = new Mention();
|
||||
$m->status_id = $status->id;
|
||||
$m->profile_id = $mentioned->id;
|
||||
$m->save();
|
||||
|
@ -118,5 +115,4 @@ class StatusEntityLexer implements ShouldQueue
|
|||
});
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -29,6 +29,7 @@ class Like extends Model
|
|||
public function toText()
|
||||
{
|
||||
$actorName = $this->actor->username;
|
||||
|
||||
return "{$actorName} ".__('notification.likedPhoto');
|
||||
}
|
||||
|
||||
|
@ -36,6 +37,7 @@ class Like extends Model
|
|||
{
|
||||
$actorName = $this->actor->username;
|
||||
$actorUrl = $this->actor->url();
|
||||
|
||||
return "<a href='{$actorUrl}' class='profile-link'>{$actorName}</a> ".
|
||||
__('notification.likedPhoto');
|
||||
}
|
||||
|
|
|
@ -6,7 +6,6 @@ use App\EmailVerification;
|
|||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Mail\Mailable;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
|
||||
class ConfirmEmail extends Mailable
|
||||
{
|
||||
|
|
|
@ -2,9 +2,9 @@
|
|||
|
||||
namespace App;
|
||||
|
||||
use Storage;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
use Storage;
|
||||
|
||||
class Media extends Model
|
||||
{
|
||||
|
@ -21,6 +21,7 @@ class Media extends Model
|
|||
{
|
||||
$path = $this->media_path;
|
||||
$url = Storage::url($path);
|
||||
|
||||
return url($url);
|
||||
}
|
||||
|
||||
|
@ -28,6 +29,7 @@ class Media extends Model
|
|||
{
|
||||
$path = $this->thumbnail_path;
|
||||
$url = Storage::url($path);
|
||||
|
||||
return url($url);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,6 +29,7 @@ class Mention extends Model
|
|||
public function toText()
|
||||
{
|
||||
$actorName = $this->status->profile->username;
|
||||
|
||||
return "{$actorName} ".__('notification.mentionedYou');
|
||||
}
|
||||
|
||||
|
@ -36,6 +37,7 @@ class Mention extends Model
|
|||
{
|
||||
$actorName = $this->status->profile->username;
|
||||
$actorUrl = $this->status->profile->url();
|
||||
|
||||
return "<a href='{$actorUrl}' class='profile-link'>{$actorName}</a> ".
|
||||
__('notification.mentionedYou');
|
||||
}
|
||||
|
|
|
@ -35,5 +35,4 @@ class Notification extends Model
|
|||
{
|
||||
return $this->belongsTo(Status::class, 'item_id', 'id');
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -2,8 +2,10 @@
|
|||
|
||||
namespace App\Observers;
|
||||
|
||||
use App\{Profile, User, UserSetting};
|
||||
use App\Jobs\AvatarPipeline\CreateAvatar;
|
||||
use App\Profile;
|
||||
use App\User;
|
||||
use App\UserSetting;
|
||||
|
||||
class UserObserver
|
||||
{
|
||||
|
@ -11,19 +13,20 @@ class UserObserver
|
|||
* Listen to the User created event.
|
||||
*
|
||||
* @param \App\User $user
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function saved(User $user)
|
||||
{
|
||||
if (empty($user->profile)) {
|
||||
$profile = new Profile;
|
||||
$profile = new Profile();
|
||||
$profile->user_id = $user->id;
|
||||
$profile->username = $user->username;
|
||||
$profile->name = $user->name;
|
||||
$pkiConfig = [
|
||||
"digest_alg" => "sha512",
|
||||
"private_key_bits" => 2048,
|
||||
"private_key_type" => OPENSSL_KEYTYPE_RSA,
|
||||
'digest_alg' => 'sha512',
|
||||
'private_key_bits' => 2048,
|
||||
'private_key_type' => OPENSSL_KEYTYPE_RSA,
|
||||
];
|
||||
$pki = openssl_pkey_new($pkiConfig);
|
||||
openssl_pkey_export($pki, $pki_private);
|
||||
|
@ -38,10 +41,9 @@ class UserObserver
|
|||
}
|
||||
|
||||
if (empty($user->settings)) {
|
||||
$settings = new UserSetting;
|
||||
$settings = new UserSetting();
|
||||
$settings->user_id = $user->id;
|
||||
$settings->save();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -2,10 +2,12 @@
|
|||
|
||||
namespace App;
|
||||
|
||||
use Auth, Cache, Storage;
|
||||
use App\Util\Lexer\PrettyNumber;
|
||||
use Auth;
|
||||
use Cache;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
use Storage;
|
||||
|
||||
class Profile extends Model
|
||||
{
|
||||
|
@ -50,6 +52,7 @@ class Profile extends Model
|
|||
public function emailUrl()
|
||||
{
|
||||
$domain = parse_url(config('app.url'), PHP_URL_HOST);
|
||||
|
||||
return $this->username.'@'.$domain;
|
||||
}
|
||||
|
||||
|
@ -81,7 +84,7 @@ class Profile extends Model
|
|||
public function following()
|
||||
{
|
||||
return $this->belongsToMany(
|
||||
Profile::class,
|
||||
self::class,
|
||||
'followers',
|
||||
'profile_id',
|
||||
'following_id'
|
||||
|
@ -91,7 +94,7 @@ class Profile extends Model
|
|||
public function followers()
|
||||
{
|
||||
return $this->belongsToMany(
|
||||
Profile::class,
|
||||
self::class,
|
||||
'followers',
|
||||
'following_id',
|
||||
'profile_id'
|
||||
|
@ -126,7 +129,7 @@ class Profile extends Model
|
|||
public function avatar()
|
||||
{
|
||||
return $this->hasOne(Avatar::class)->withDefault([
|
||||
'media_path' => 'public/avatars/default.png'
|
||||
'media_path' => 'public/avatars/default.png',
|
||||
]);
|
||||
}
|
||||
|
||||
|
@ -136,8 +139,10 @@ class Profile extends Model
|
|||
$path = optional($this->avatar)->media_path;
|
||||
$version = hash('sha1', $this->avatar->created_at);
|
||||
$path = "{$path}?v={$version}";
|
||||
|
||||
return url(Storage::url($path));
|
||||
});
|
||||
|
||||
return $url;
|
||||
}
|
||||
|
||||
|
@ -168,7 +173,7 @@ class Profile extends Model
|
|||
->pluck('following_id');
|
||||
$recommended = [];
|
||||
foreach ($following as $follow) {
|
||||
$recommended[] = Profile::findOrFail($follow);
|
||||
$recommended[] = self::findOrFail($follow);
|
||||
}
|
||||
|
||||
return $recommended;
|
||||
|
@ -179,6 +184,7 @@ class Profile extends Model
|
|||
if ($this->remote_url) {
|
||||
return;
|
||||
}
|
||||
|
||||
return $this->permalink('#main-key');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,9 +2,10 @@
|
|||
|
||||
namespace App\Providers;
|
||||
|
||||
use App\User;
|
||||
use Auth, Horizon;
|
||||
use App\Observers\UserObserver;
|
||||
use App\User;
|
||||
use Auth;
|
||||
use Horizon;
|
||||
use Illuminate\Support\Facades\Blade;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
|
@ -28,14 +29,16 @@ class AppServiceProvider extends ServiceProvider
|
|||
|
||||
Blade::directive('prettyNumber', function ($expression) {
|
||||
$num = $expression;
|
||||
$abbrevs = array(12 => "T", 9 => "B", 6 => "M", 3 => "K", 0 => "");
|
||||
$abbrevs = [12 => 'T', 9 => 'B', 6 => 'M', 3 => 'K', 0 => ''];
|
||||
foreach ($abbrevs as $exponent => $abbrev) {
|
||||
if ($expression >= pow(10, $exponent)) {
|
||||
$display_num = $expression / pow(10, $exponent);
|
||||
$num = number_format($display_num, 0).$abbrev;
|
||||
|
||||
return "<?php echo '$num'; ?>";
|
||||
}
|
||||
}
|
||||
|
||||
return "<?php echo $num; ?>";
|
||||
});
|
||||
|
||||
|
@ -46,13 +49,16 @@ class AppServiceProvider extends ServiceProvider
|
|||
$units = $short ?
|
||||
['B', 'k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y'] :
|
||||
['B', 'kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
|
||||
for($i = 0; ($size / 1024) > 0.9; $i++, $size /= 1024) {}
|
||||
for ($i = 0; ($size / 1024) > 0.9; $i++, $size /= 1024) {
|
||||
}
|
||||
$res = round($size, $precision).$units[$i];
|
||||
|
||||
return "<?php echo '$res'; ?>";
|
||||
});
|
||||
|
||||
Blade::directive('maxFileSize', function () {
|
||||
$value = config('pixelfed.max_photo_size');
|
||||
|
||||
return \App\Util\Lexer\PrettyNumber::size($value, true);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
namespace App\Providers;
|
||||
|
||||
use Illuminate\Support\Facades\Gate;
|
||||
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
|
||||
|
||||
class AuthServiceProvider extends ServiceProvider
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
|
||||
namespace App\Providers;
|
||||
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
use Illuminate\Support\Facades\Broadcast;
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
|
||||
class BroadcastServiceProvider extends ServiceProvider
|
||||
{
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
|
||||
namespace App\Providers;
|
||||
|
||||
use Illuminate\Support\Facades\Event;
|
||||
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
|
||||
use Illuminate\Support\Facades\Event;
|
||||
|
||||
class EventServiceProvider extends ServiceProvider
|
||||
{
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
|
||||
namespace App\Providers;
|
||||
|
||||
use Illuminate\Support\Facades\Route;
|
||||
use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider;
|
||||
use Illuminate\Support\Facades\Route;
|
||||
|
||||
class RouteServiceProvider extends ServiceProvider
|
||||
{
|
||||
|
|
|
@ -30,6 +30,7 @@ class Report extends Model
|
|||
$column = 'id';
|
||||
break;
|
||||
}
|
||||
|
||||
return (new $class())->where($column, $this->object_id)->firstOrFail();
|
||||
}
|
||||
|
||||
|
|
|
@ -2,9 +2,10 @@
|
|||
|
||||
namespace App;
|
||||
|
||||
use Auth, Storage;
|
||||
use Auth;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
use Storage;
|
||||
|
||||
class Status extends Model
|
||||
{
|
||||
|
@ -36,6 +37,7 @@ class Status extends Model
|
|||
{
|
||||
$media = $this->firstMedia();
|
||||
$type = explode('/', $media->mime);
|
||||
|
||||
return $type[0];
|
||||
}
|
||||
|
||||
|
@ -44,8 +46,9 @@ class Status extends Model
|
|||
$type = $this->viewType();
|
||||
$is_nsfw = !$showNsfw ? $this->is_nsfw : false;
|
||||
if ($this->media->count() == 0 || $is_nsfw || $type != 'image') {
|
||||
return "data:image/gif;base64,R0lGODlhAQABAIAAAMLCwgAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw==";
|
||||
return 'data:image/gif;base64,R0lGODlhAQABAIAAAMLCwgAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw==';
|
||||
}
|
||||
|
||||
return url(Storage::url($this->firstMedia()->thumbnail_path));
|
||||
}
|
||||
|
||||
|
@ -58,6 +61,7 @@ class Status extends Model
|
|||
$pid = $this->in_reply_to_id;
|
||||
$path = config('app.url')."/p/{$username}/{$pid}/c/{$id}";
|
||||
}
|
||||
|
||||
return url($path);
|
||||
}
|
||||
|
||||
|
@ -66,6 +70,7 @@ class Status extends Model
|
|||
$id = $this->id;
|
||||
$username = $this->profile->username;
|
||||
$path = config('app.url')."/p/{$username}/{$id}{$suffix}";
|
||||
|
||||
return url($path);
|
||||
}
|
||||
|
||||
|
@ -80,6 +85,7 @@ class Status extends Model
|
|||
$path = $media->media_path;
|
||||
$hash = is_null($media->processed_at) ? md5('unprocessed') : md5($media->created_at);
|
||||
$url = Storage::url($path)."?v={$hash}";
|
||||
|
||||
return url($url);
|
||||
}
|
||||
|
||||
|
@ -91,12 +97,13 @@ class Status extends Model
|
|||
public function liked() : bool
|
||||
{
|
||||
$profile = Auth::user()->profile;
|
||||
|
||||
return Like::whereProfileId($profile->id)->whereStatusId($this->id)->count();
|
||||
}
|
||||
|
||||
public function comments()
|
||||
{
|
||||
return $this->hasMany(Status::class, 'in_reply_to_id');
|
||||
return $this->hasMany(self::class, 'in_reply_to_id');
|
||||
}
|
||||
|
||||
public function bookmarked()
|
||||
|
@ -105,25 +112,27 @@ class Status extends Model
|
|||
return 0;
|
||||
}
|
||||
$profile = Auth::user()->profile;
|
||||
|
||||
return Bookmark::whereProfileId($profile->id)->whereStatusId($this->id)->count();
|
||||
}
|
||||
|
||||
public function shares()
|
||||
{
|
||||
return $this->hasMany(Status::class, 'reblog_of_id');
|
||||
return $this->hasMany(self::class, 'reblog_of_id');
|
||||
}
|
||||
|
||||
public function shared() : bool
|
||||
{
|
||||
$profile = Auth::user()->profile;
|
||||
return Status::whereProfileId($profile->id)->whereReblogOfId($this->id)->count();
|
||||
|
||||
return self::whereProfileId($profile->id)->whereReblogOfId($this->id)->count();
|
||||
}
|
||||
|
||||
public function parent()
|
||||
{
|
||||
$parent = $this->in_reply_to_id ?? $this->reblog_of_id;
|
||||
if (!empty($parent)) {
|
||||
return Status::findOrFail($parent);
|
||||
return self::findOrFail($parent);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -167,23 +176,25 @@ class Status extends Model
|
|||
$mediaCollection = [];
|
||||
foreach ($media as $image) {
|
||||
$mediaCollection[] = [
|
||||
"type" => "Link",
|
||||
"href" => $image->url(),
|
||||
"mediaType" => $image->mime
|
||||
'type' => 'Link',
|
||||
'href' => $image->url(),
|
||||
'mediaType' => $image->mime,
|
||||
];
|
||||
}
|
||||
$obj = [
|
||||
"@context" => "https://www.w3.org/ns/activitystreams",
|
||||
"type" => "Image",
|
||||
"name" => null,
|
||||
"url" => $mediaCollection
|
||||
'@context' => 'https://www.w3.org/ns/activitystreams',
|
||||
'type' => 'Image',
|
||||
'name' => null,
|
||||
'url' => $mediaCollection,
|
||||
];
|
||||
|
||||
return $obj;
|
||||
}
|
||||
|
||||
public function replyToText()
|
||||
{
|
||||
$actorName = $this->profile->username;
|
||||
|
||||
return "{$actorName} ".__('notification.commented');
|
||||
}
|
||||
|
||||
|
@ -191,6 +202,7 @@ class Status extends Model
|
|||
{
|
||||
$actorName = $this->profile->username;
|
||||
$actorUrl = $this->profile->url();
|
||||
|
||||
return "<a href='{$actorUrl}' class='profile-link'>{$actorName}</a> ".
|
||||
__('notification.commented');
|
||||
}
|
||||
|
|
|
@ -7,7 +7,6 @@ use League\Fractal;
|
|||
|
||||
class ProfileOutbox extends Fractal\TransformerAbstract
|
||||
{
|
||||
|
||||
public function transform(Profile $profile)
|
||||
{
|
||||
$count = $profile->statuses()->count();
|
||||
|
@ -19,7 +18,7 @@ class ProfileOutbox extends Fractal\TransformerAbstract
|
|||
'actor' => $i->profile->url(),
|
||||
'published' => $i->created_at->toISO8601String(),
|
||||
'to' => [
|
||||
'https://www.w3.org/ns/activitystreams#Public'
|
||||
'https://www.w3.org/ns/activitystreams#Public',
|
||||
],
|
||||
'cc' => [
|
||||
$i->profile->permalink('/followers'),
|
||||
|
@ -41,7 +40,7 @@ class ProfileOutbox extends Fractal\TransformerAbstract
|
|||
'attributedTo' => $i->profile->permalink(),
|
||||
'to' => [
|
||||
// TODO: handle proper scope
|
||||
'https://www.w3.org/ns/activitystreams#Public'
|
||||
'https://www.w3.org/ns/activitystreams#Public',
|
||||
],
|
||||
'cc' => [
|
||||
// TODO: add cc's
|
||||
|
@ -57,12 +56,13 @@ class ProfileOutbox extends Fractal\TransformerAbstract
|
|||
'type' => 'Document',
|
||||
'mediaType' => $i->firstMedia()->mime,
|
||||
'url' => $i->firstMedia()->url(),
|
||||
'name' => null
|
||||
]
|
||||
'name' => null,
|
||||
],
|
||||
],
|
||||
'tag' => [],
|
||||
],
|
||||
'tag' => []
|
||||
]
|
||||
];
|
||||
|
||||
return $item;
|
||||
});
|
||||
|
||||
|
@ -71,8 +71,7 @@ class ProfileOutbox extends Fractal\TransformerAbstract
|
|||
'id' => $profile->permalink('/outbox'),
|
||||
'type' => 'OrderedCollection',
|
||||
'totalItems' => $count,
|
||||
'orderedItems' => $statuses
|
||||
'orderedItems' => $statuses,
|
||||
];
|
||||
}
|
||||
|
||||
}
|
|
@ -7,7 +7,6 @@ use League\Fractal;
|
|||
|
||||
class ProfileTransformer extends Fractal\TransformerAbstract
|
||||
{
|
||||
|
||||
public function transform(Profile $profile)
|
||||
{
|
||||
return [
|
||||
|
@ -15,11 +14,11 @@ class ProfileTransformer extends Fractal\TransformerAbstract
|
|||
'https://www.w3.org/ns/activitystreams',
|
||||
'https://w3id.org/security/v1',
|
||||
[
|
||||
"manuallyApprovesFollowers" => "as:manuallyApprovesFollowers",
|
||||
"featured" => [
|
||||
"https://pixelfed.org/ns#featured" => ["@type" => "@id"],
|
||||
]
|
||||
]
|
||||
'manuallyApprovesFollowers' => 'as:manuallyApprovesFollowers',
|
||||
'featured' => [
|
||||
'https://pixelfed.org/ns#featured' => ['@type' => '@id'],
|
||||
],
|
||||
],
|
||||
],
|
||||
'id' => $profile->permalink(),
|
||||
'type' => 'Person',
|
||||
|
@ -38,17 +37,16 @@ class ProfileTransformer extends Fractal\TransformerAbstract
|
|||
'publicKey' => [
|
||||
'id' => $profile->permalink().'#main-key',
|
||||
'owner' => $profile->permalink(),
|
||||
'publicKeyPem' => $profile->public_key
|
||||
'publicKeyPem' => $profile->public_key,
|
||||
],
|
||||
'endpoints' => [
|
||||
'sharedInbox' => config('routes.api.sharedInbox')
|
||||
'sharedInbox' => config('routes.api.sharedInbox'),
|
||||
],
|
||||
'icon' => [
|
||||
'type' => 'Image',
|
||||
'mediaType' => 'image/jpeg',
|
||||
'url' => $profile->avatarUrl()
|
||||
]
|
||||
'url' => $profile->avatarUrl(),
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
}
|
|
@ -2,12 +2,11 @@
|
|||
|
||||
namespace App\Transformer\ActivityPub;
|
||||
|
||||
use App\{Profile, Status};
|
||||
use App\Status;
|
||||
use League\Fractal;
|
||||
|
||||
class StatusTransformer extends Fractal\TransformerAbstract
|
||||
{
|
||||
|
||||
public function transform(Status $status)
|
||||
{
|
||||
return [
|
||||
|
@ -15,11 +14,11 @@ class StatusTransformer extends Fractal\TransformerAbstract
|
|||
'https://www.w3.org/ns/activitystreams',
|
||||
'https://w3id.org/security/v1',
|
||||
[
|
||||
"manuallyApprovesFollowers" => "as:manuallyApprovesFollowers",
|
||||
"featured" => [
|
||||
"https://pixelfed.org/ns#featured" => ["@type" => "@id"],
|
||||
]
|
||||
]
|
||||
'manuallyApprovesFollowers' => 'as:manuallyApprovesFollowers',
|
||||
'featured' => [
|
||||
'https://pixelfed.org/ns#featured' => ['@type' => '@id'],
|
||||
],
|
||||
],
|
||||
],
|
||||
'id' => $status->url(),
|
||||
|
||||
|
@ -37,7 +36,7 @@ class StatusTransformer extends Fractal\TransformerAbstract
|
|||
'attributedTo' => $status->profile->permalink(),
|
||||
'to' => [
|
||||
// TODO: handle proper scope
|
||||
'https://www.w3.org/ns/activitystreams#Public'
|
||||
'https://www.w3.org/ns/activitystreams#Public',
|
||||
],
|
||||
'cc' => [
|
||||
// TODO: add cc's
|
||||
|
@ -51,11 +50,10 @@ class StatusTransformer extends Fractal\TransformerAbstract
|
|||
'type' => 'Document',
|
||||
'mediaType' => $media->mime,
|
||||
'url' => $media->url(),
|
||||
'name' => null
|
||||
'name' => null,
|
||||
];
|
||||
}),
|
||||
'tag' => []
|
||||
'tag' => [],
|
||||
];
|
||||
}
|
||||
|
||||
}
|
|
@ -27,7 +27,7 @@ class AccountTransformer extends Fractal\TransformerAbstract
|
|||
'header_static' => '',
|
||||
'moved' => null,
|
||||
'fields' => null,
|
||||
'bot' => null
|
||||
'bot' => null,
|
||||
];
|
||||
}
|
||||
}
|
|
@ -10,7 +10,7 @@ class ApplicationTransformer extends Fractal\TransformerAbstract
|
|||
{
|
||||
return [
|
||||
'name' => '',
|
||||
'website' => null
|
||||
'website' => null,
|
||||
];
|
||||
}
|
||||
}
|
|
@ -4,7 +4,6 @@ namespace App\Transformer\Api;
|
|||
|
||||
use App\Hashtag;
|
||||
use League\Fractal;
|
||||
use League\Fractal\Serializer\ArraySerializer;
|
||||
|
||||
class HashtagTransformer extends Fractal\TransformerAbstract
|
||||
{
|
||||
|
|
|
@ -4,7 +4,6 @@ namespace App\Transformer\Api;
|
|||
|
||||
use App\Media;
|
||||
use League\Fractal;
|
||||
use League\Fractal\Serializer\ArraySerializer;
|
||||
|
||||
class MediaTransformer extends Fractal\TransformerAbstract
|
||||
{
|
||||
|
@ -18,7 +17,7 @@ class MediaTransformer extends Fractal\TransformerAbstract
|
|||
'preview_url' => $media->thumbnailUrl(),
|
||||
'text_url' => null,
|
||||
'meta' => null,
|
||||
'description' => null
|
||||
'description' => null,
|
||||
];
|
||||
}
|
||||
}
|
|
@ -11,7 +11,7 @@ class StatusTransformer extends Fractal\TransformerAbstract
|
|||
'account',
|
||||
'mentions',
|
||||
'media_attachments',
|
||||
'tags'
|
||||
'tags',
|
||||
];
|
||||
|
||||
public function transform(Status $status)
|
||||
|
@ -39,31 +39,35 @@ class StatusTransformer extends Fractal\TransformerAbstract
|
|||
'visibility' => $status->visibility,
|
||||
'application' => null,
|
||||
'language' => null,
|
||||
'pinned' => null
|
||||
'pinned' => null,
|
||||
];
|
||||
}
|
||||
|
||||
public function includeAccount(Status $status)
|
||||
{
|
||||
$account = $status->profile;
|
||||
return $this->item($account, new AccountTransformer);
|
||||
|
||||
return $this->item($account, new AccountTransformer());
|
||||
}
|
||||
|
||||
public function includeMentions(Status $status)
|
||||
{
|
||||
$mentions = $status->mentions;
|
||||
return $this->collection($mentions, new MentionTransformer);
|
||||
|
||||
return $this->collection($mentions, new MentionTransformer());
|
||||
}
|
||||
|
||||
public function includeMediaAttachments(Status $status)
|
||||
{
|
||||
$media = $status->media;
|
||||
return $this->collection($media, new MediaTransformer);
|
||||
|
||||
return $this->collection($media, new MediaTransformer());
|
||||
}
|
||||
|
||||
public function includeTags(Status $status)
|
||||
{
|
||||
$tags = $status->hashtags;
|
||||
return $this->collection($tags, new HashtagTransformer);
|
||||
|
||||
return $this->collection($tags, new HashtagTransformer());
|
||||
}
|
||||
}
|
|
@ -2,9 +2,9 @@
|
|||
|
||||
namespace App;
|
||||
|
||||
use Illuminate\Notifications\Notifiable;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
use Illuminate\Foundation\Auth\User as Authenticatable;
|
||||
use Illuminate\Notifications\Notifiable;
|
||||
|
||||
class User extends Authenticatable
|
||||
{
|
||||
|
|
|
@ -10,6 +10,6 @@ class UserFilter extends Model
|
|||
'user_id',
|
||||
'filterable_id',
|
||||
'filterable_type',
|
||||
'filter_type'
|
||||
'filter_type',
|
||||
];
|
||||
}
|
||||
|
|
|
@ -4,10 +4,10 @@ namespace App\Util\ActivityPub\Concern;
|
|||
|
||||
use Zttp\Zttp;
|
||||
|
||||
class HTTPSignature {
|
||||
|
||||
class HTTPSignature
|
||||
{
|
||||
protected $localhosts = [
|
||||
'127.0.0.1', 'localhost', '::1'
|
||||
'127.0.0.1', 'localhost', '::1',
|
||||
];
|
||||
public $profile;
|
||||
public $is_url;
|
||||
|
@ -20,6 +20,7 @@ class HTTPSignature {
|
|||
}
|
||||
|
||||
$url = $this->profile;
|
||||
|
||||
try {
|
||||
$url = filter_var($url, FILTER_VALIDATE_URL);
|
||||
$parsed = parse_url($url, PHP_URL_HOST);
|
||||
|
@ -29,6 +30,7 @@ class HTTPSignature {
|
|||
} catch (Exception $e) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -48,7 +50,7 @@ class HTTPSignature {
|
|||
$url = $this->profile;
|
||||
$res = Zttp::timeout(30)->withHeaders([
|
||||
'Accept' => 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"',
|
||||
'User-Agent' => 'PixelFedBot v0.1 - https://pixelfed.org'
|
||||
'User-Agent' => 'PixelFedBot v0.1 - https://pixelfed.org',
|
||||
])->get($url);
|
||||
$actor = json_decode($res->getBody(), true);
|
||||
} catch (Exception $e) {
|
||||
|
@ -74,21 +76,19 @@ class HTTPSignature {
|
|||
'Accept' => 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"',
|
||||
'Date' => date('D, d M Y h:i:s').' GMT',
|
||||
'Content-Type' => 'application/activity+json',
|
||||
'User-Agent' => 'PixelFedBot - https://pixelfed.org'
|
||||
'User-Agent' => 'PixelFedBot - https://pixelfed.org',
|
||||
];
|
||||
|
||||
$response = $client->post($url, [
|
||||
'options' => [
|
||||
'allow_redirects' => false,
|
||||
'verify' => true,
|
||||
'timeout' => 30
|
||||
'timeout' => 30,
|
||||
],
|
||||
'headers' => $headers,
|
||||
'body' => $body
|
||||
'body' => $body,
|
||||
]);
|
||||
|
||||
return $response->getBody();
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -2,10 +2,10 @@
|
|||
|
||||
namespace App\Util\ActivityPub;
|
||||
|
||||
use \Zttp\Zttp;
|
||||
|
||||
class DiscoverActor {
|
||||
use Zttp\Zttp;
|
||||
|
||||
class DiscoverActor
|
||||
{
|
||||
protected $url;
|
||||
protected $response;
|
||||
|
||||
|
@ -18,9 +18,10 @@ class DiscoverActor {
|
|||
{
|
||||
$res = Zttp::withHeaders([
|
||||
'Accept' => 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"',
|
||||
'User-Agent' => 'PixelFedBot - https://pixelfed.org'
|
||||
'User-Agent' => 'PixelFedBot - https://pixelfed.org',
|
||||
])->get($this->url);
|
||||
$this->response = $res->body();
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
@ -45,5 +46,4 @@ class DiscoverActor {
|
|||
|
||||
return $res;
|
||||
}
|
||||
|
||||
}
|
|
@ -2,11 +2,11 @@
|
|||
|
||||
namespace App\Util\ActivityPub;
|
||||
|
||||
use App\Jobs\AvatarPipeline\CreateAvatar;
|
||||
use App\{Follower, Like, Profile, Like, Status, User};
|
||||
|
||||
class Inbox {
|
||||
use App\Like;
|
||||
use App\Profile;
|
||||
|
||||
class Inbox
|
||||
{
|
||||
protected $request;
|
||||
protected $profile;
|
||||
protected $payload;
|
||||
|
@ -58,7 +58,6 @@ class Inbox {
|
|||
{
|
||||
$actor = $this->payload['object'];
|
||||
$target = $this->profile;
|
||||
|
||||
}
|
||||
|
||||
public function actorFirstOrCreate($actorUrl)
|
||||
|
@ -73,7 +72,7 @@ class Inbox {
|
|||
$username = $res['preferredUsername'];
|
||||
$remoteUsername = "@{$username}@{$domain}";
|
||||
|
||||
$profile = new Profile;
|
||||
$profile = new Profile();
|
||||
$profile->user_id = null;
|
||||
$profile->domain = $domain;
|
||||
$profile->username = $remoteUsername;
|
||||
|
@ -82,7 +81,5 @@ class Inbox {
|
|||
$profile->sharedInbox = $res['endpoints']['sharedInbox'];
|
||||
$profile->remote_url = $res['url'];
|
||||
$profile->save();
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -12,7 +12,7 @@ class HashPreprocessor implements \Bitverse\Identicon\Preprocessor\PreprocessorI
|
|||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function process($string)
|
||||
{
|
||||
|
|
|
@ -5,17 +5,12 @@
|
|||
* @author Nick Pope <nick@nickpope.me.uk>
|
||||
* @copyright Copyright © 2010, Mike Cochrane, Nick Pope
|
||||
* @license http://www.apache.org/licenses/LICENSE-2.0 Apache License v2.0
|
||||
* @package Twitter.Text
|
||||
*/
|
||||
|
||||
namespace App\Util\Lexer;
|
||||
|
||||
use App\Util\Lexer\Regex;
|
||||
use App\Util\Lexer\Extractor;
|
||||
use App\Util\Lexer\StringUtils;
|
||||
|
||||
/**
|
||||
* Twitter Autolink Class
|
||||
* Twitter Autolink Class.
|
||||
*
|
||||
* Parses tweets and generates HTML anchor tags around URLs, usernames,
|
||||
* username/list pairs and hashtags.
|
||||
|
@ -28,11 +23,9 @@ use App\Util\Lexer\StringUtils;
|
|||
* @author Nick Pope <nick@nickpope.me.uk>
|
||||
* @copyright Copyright © 2010, Mike Cochrane, Nick Pope
|
||||
* @license http://www.apache.org/licenses/LICENSE-2.0 Apache License v2.0
|
||||
* @package Twitter.Text
|
||||
*/
|
||||
class Autolink extends Regex
|
||||
{
|
||||
|
||||
/**
|
||||
* CSS class for auto-linked URLs.
|
||||
*
|
||||
|
@ -134,14 +127,13 @@ class Autolink extends Regex
|
|||
protected $target = '_blank';
|
||||
|
||||
/**
|
||||
* attribute for invisible span tag
|
||||
* attribute for invisible span tag.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $invisibleTagAttrs = "style='position:absolute;left:-9999px;'";
|
||||
|
||||
/**
|
||||
*
|
||||
* @var Extractor
|
||||
*/
|
||||
protected $extractor = null;
|
||||
|
@ -187,7 +179,7 @@ class Autolink extends Regex
|
|||
$this->extractor = Extractor::create();
|
||||
$this->url_base_user = config('app.url').'/';
|
||||
$this->url_base_list = config('app.url').'/';
|
||||
$this->url_base_hash = config('app.url') . "/discover/tags/";
|
||||
$this->url_base_hash = config('app.url').'/discover/tags/';
|
||||
$this->url_base_cash = config('app.url').'/search?q=%24';
|
||||
}
|
||||
|
||||
|
@ -211,6 +203,7 @@ class Autolink extends Regex
|
|||
public function setURLClass($v)
|
||||
{
|
||||
$this->class_url = trim($v);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
@ -234,6 +227,7 @@ class Autolink extends Regex
|
|||
public function setUsernameClass($v)
|
||||
{
|
||||
$this->class_user = trim($v);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
@ -257,6 +251,7 @@ class Autolink extends Regex
|
|||
public function setListClass($v)
|
||||
{
|
||||
$this->class_list = trim($v);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
@ -280,6 +275,7 @@ class Autolink extends Regex
|
|||
public function setHashtagClass($v)
|
||||
{
|
||||
$this->class_hash = trim($v);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
@ -303,6 +299,7 @@ class Autolink extends Regex
|
|||
public function setCashtagClass($v)
|
||||
{
|
||||
$this->class_cash = trim($v);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
@ -326,6 +323,7 @@ class Autolink extends Regex
|
|||
public function setNoFollow($v)
|
||||
{
|
||||
$this->nofollow = $v;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
@ -359,6 +357,7 @@ class Autolink extends Regex
|
|||
public function setExternal($v)
|
||||
{
|
||||
$this->external = $v;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
@ -390,15 +389,18 @@ class Autolink extends Regex
|
|||
public function setTarget($v)
|
||||
{
|
||||
$this->target = trim($v);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Autolink with entities
|
||||
* Autolink with entities.
|
||||
*
|
||||
* @param string $tweet
|
||||
* @param array $entities
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @since 1.1.0
|
||||
*/
|
||||
public function autoLinkEntities($tweet = null, $entities = null)
|
||||
|
@ -428,6 +430,7 @@ class Autolink extends Regex
|
|||
$beginIndex = $entity['indices'][1];
|
||||
}
|
||||
$text .= StringUtils::substr($tweet, $beginIndex, StringUtils::strlen($tweet));
|
||||
|
||||
return $text;
|
||||
}
|
||||
|
||||
|
@ -436,13 +439,15 @@ class Autolink extends Regex
|
|||
*
|
||||
* @param string The tweet to be converted
|
||||
* @param mixed The entities info
|
||||
*
|
||||
* @return string that auto-link HTML added
|
||||
*
|
||||
* @since 1.1.0
|
||||
*/
|
||||
public function autoLinkWithJson($tweet = null, $json = null)
|
||||
{
|
||||
// concatenate entities
|
||||
$entities = array();
|
||||
$entities = [];
|
||||
if (is_object($json)) {
|
||||
$json = $this->object2array($json);
|
||||
}
|
||||
|
@ -460,13 +465,15 @@ class Autolink extends Regex
|
|||
}
|
||||
|
||||
$entities = $this->extractor->removeOverlappingEntities($entities);
|
||||
|
||||
return $this->autoLinkEntities($tweet, $entities);
|
||||
}
|
||||
|
||||
/**
|
||||
* convert Object to Array
|
||||
* convert Object to Array.
|
||||
*
|
||||
* @param mixed $obj
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function object2array($obj)
|
||||
|
@ -477,6 +484,7 @@ class Autolink extends Regex
|
|||
$array[$key] = $this->object2array($var);
|
||||
}
|
||||
}
|
||||
|
||||
return $array;
|
||||
}
|
||||
|
||||
|
@ -484,7 +492,9 @@ class Autolink extends Regex
|
|||
* Auto-link hashtags, URLs, usernames and lists.
|
||||
*
|
||||
* @param string The tweet to be converted
|
||||
*
|
||||
* @return string that auto-link HTML added
|
||||
*
|
||||
* @since 1.1.0
|
||||
*/
|
||||
public function autoLink($tweet = null)
|
||||
|
@ -493,6 +503,7 @@ class Autolink extends Regex
|
|||
$tweet = $this->tweet;
|
||||
}
|
||||
$entities = $this->extractor->extractURLWithoutProtocol(false)->extractEntitiesWithIndices($tweet);
|
||||
|
||||
return $this->autoLinkEntities($tweet, $entities);
|
||||
}
|
||||
|
||||
|
@ -502,6 +513,7 @@ class Autolink extends Regex
|
|||
* added.
|
||||
*
|
||||
* @return string that auto-link HTML added
|
||||
*
|
||||
* @since 1.1.0
|
||||
*/
|
||||
public function autoLinkUsernamesAndLists($tweet = null)
|
||||
|
@ -510,6 +522,7 @@ class Autolink extends Regex
|
|||
$tweet = $this->tweet;
|
||||
}
|
||||
$entities = $this->extractor->extractMentionsOrListsWithIndices($tweet);
|
||||
|
||||
return $this->autoLinkEntities($tweet, $entities);
|
||||
}
|
||||
|
||||
|
@ -518,6 +531,7 @@ class Autolink extends Regex
|
|||
* added.
|
||||
*
|
||||
* @return string that auto-link HTML added
|
||||
*
|
||||
* @since 1.1.0
|
||||
*/
|
||||
public function autoLinkHashtags($tweet = null)
|
||||
|
@ -526,6 +540,7 @@ class Autolink extends Regex
|
|||
$tweet = $this->tweet;
|
||||
}
|
||||
$entities = $this->extractor->extractHashtagsWithIndices($tweet);
|
||||
|
||||
return $this->autoLinkEntities($tweet, $entities);
|
||||
}
|
||||
|
||||
|
@ -535,6 +550,7 @@ class Autolink extends Regex
|
|||
* This only auto-links URLs with protocol.
|
||||
*
|
||||
* @return string that auto-link HTML added
|
||||
*
|
||||
* @since 1.1.0
|
||||
*/
|
||||
public function autoLinkURLs($tweet = null)
|
||||
|
@ -543,6 +559,7 @@ class Autolink extends Regex
|
|||
$tweet = $this->tweet;
|
||||
}
|
||||
$entities = $this->extractor->extractURLWithoutProtocol(false)->extractURLsWithIndices($tweet);
|
||||
|
||||
return $this->autoLinkEntities($tweet, $entities);
|
||||
}
|
||||
|
||||
|
@ -551,6 +568,7 @@ class Autolink extends Regex
|
|||
* added.
|
||||
*
|
||||
* @return string that auto-link HTML added
|
||||
*
|
||||
* @since 1.1.0
|
||||
*/
|
||||
public function autoLinkCashtags($tweet = null)
|
||||
|
@ -559,6 +577,7 @@ class Autolink extends Regex
|
|||
$tweet = $this->tweet;
|
||||
}
|
||||
$entities = $this->extractor->extractCashtagsWithIndices($tweet);
|
||||
|
||||
return $this->autoLinkEntities($tweet, $entities);
|
||||
}
|
||||
|
||||
|
@ -639,10 +658,11 @@ class Autolink extends Regex
|
|||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param array $entity
|
||||
* @param string $tweet
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @since 1.1.0
|
||||
*/
|
||||
public function linkToHashtag($entity, $tweet = null)
|
||||
|
@ -651,8 +671,8 @@ class Autolink extends Regex
|
|||
$tweet = $this->tweet;
|
||||
}
|
||||
$this->target = false;
|
||||
$attributes = array();
|
||||
$class = array();
|
||||
$attributes = [];
|
||||
$class = [];
|
||||
$hash = StringUtils::substr($tweet, $entity['indices'][0], 1);
|
||||
$linkText = $hash.$entity['hashtag'];
|
||||
|
||||
|
@ -665,29 +685,30 @@ class Autolink extends Regex
|
|||
$class[] = 'rtl';
|
||||
}
|
||||
if (!empty($class)) {
|
||||
$attributes['class'] = join(' ', $class);
|
||||
$attributes['class'] = implode(' ', $class);
|
||||
}
|
||||
|
||||
return $this->linkToText($entity, $linkText, $attributes);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param array $entity
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @since 1.1.0
|
||||
*/
|
||||
public function linkToMentionAndList($entity)
|
||||
{
|
||||
$attributes = array();
|
||||
$attributes = [];
|
||||
|
||||
if (!empty($entity['list_slug'])) {
|
||||
# Replace the list and username
|
||||
// Replace the list and username
|
||||
$linkText = $entity['screen_name'].$entity['list_slug'];
|
||||
$class = $this->class_list;
|
||||
$url = $this->url_base_list.$linkText;
|
||||
} else {
|
||||
# Replace the username
|
||||
// Replace the username
|
||||
$linkText = $entity['screen_name'];
|
||||
$class = $this->class_user;
|
||||
$url = $this->url_base_user.$linkText;
|
||||
|
@ -701,10 +722,11 @@ class Autolink extends Regex
|
|||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param array $entity
|
||||
* @param string $tweet
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @since 1.1.0
|
||||
*/
|
||||
public function linkToCashtag($entity, $tweet = null)
|
||||
|
@ -712,7 +734,7 @@ class Autolink extends Regex
|
|||
if (is_null($tweet)) {
|
||||
$tweet = $this->tweet;
|
||||
}
|
||||
$attributes = array();
|
||||
$attributes = [];
|
||||
$doller = StringUtils::substr($tweet, $entity['indices'][0], 1);
|
||||
$linkText = $doller.$entity['cashtag'];
|
||||
$attributes['href'] = $this->url_base_cash.$entity['cashtag'];
|
||||
|
@ -725,16 +747,17 @@ class Autolink extends Regex
|
|||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param array $entity
|
||||
* @param string $text
|
||||
* @param array $attributes
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @since 1.1.0
|
||||
*/
|
||||
public function linkToText(array $entity, $text, $attributes = array())
|
||||
public function linkToText(array $entity, $text, $attributes = [])
|
||||
{
|
||||
$rel = array();
|
||||
$rel = [];
|
||||
if ($this->external) {
|
||||
$rel[] = 'external';
|
||||
}
|
||||
|
@ -745,7 +768,7 @@ class Autolink extends Regex
|
|||
$rel[] = 'noopener';
|
||||
}
|
||||
if (!empty($rel)) {
|
||||
$attributes['rel'] = join(' ', $rel);
|
||||
$attributes['rel'] = implode(' ', $rel);
|
||||
}
|
||||
if ($this->target) {
|
||||
$attributes['target'] = $this->target;
|
||||
|
@ -755,13 +778,15 @@ class Autolink extends Regex
|
|||
$link .= ' '.$key.'="'.$this->escapeHTML($val).'"';
|
||||
}
|
||||
$link .= '>'.$text.'</a>';
|
||||
|
||||
return $link;
|
||||
}
|
||||
|
||||
/**
|
||||
* html escape
|
||||
* html escape.
|
||||
*
|
||||
* @param string $text
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function escapeHTML($text)
|
||||
|
|
|
@ -5,16 +5,12 @@
|
|||
* @author Nick Pope <nick@nickpope.me.uk>
|
||||
* @copyright Copyright © 2010, Mike Cochrane, Nick Pope
|
||||
* @license http://www.apache.org/licenses/LICENSE-2.0 Apache License v2.0
|
||||
* @package Twitter.Text
|
||||
*/
|
||||
|
||||
namespace App\Util\Lexer;
|
||||
|
||||
use App\Util\Lexer\Regex;
|
||||
use App\Util\Lexer\StringUtils;
|
||||
|
||||
/**
|
||||
* Twitter Extractor Class
|
||||
* Twitter Extractor Class.
|
||||
*
|
||||
* Parses tweets and extracts URLs, usernames, username/list pairs and
|
||||
* hashtags.
|
||||
|
@ -27,13 +23,11 @@ use App\Util\Lexer\StringUtils;
|
|||
* @author Nick Pope <nick@nickpope.me.uk>
|
||||
* @copyright Copyright © 2010, Mike Cochrane, Nick Pope
|
||||
* @license http://www.apache.org/licenses/LICENSE-2.0 Apache License v2.0
|
||||
* @package Twitter.Text
|
||||
*/
|
||||
class Extractor extends Regex
|
||||
{
|
||||
|
||||
/**
|
||||
* @var boolean
|
||||
* @var bool
|
||||
*/
|
||||
protected $extractURLWithoutProtocol = true;
|
||||
|
||||
|
@ -68,6 +62,7 @@ class Extractor extends Regex
|
|||
* the extracted elements.
|
||||
*
|
||||
* @param string $tweet The tweet to extract.
|
||||
*
|
||||
* @return array The elements in the tweet.
|
||||
*/
|
||||
public function extract($tweet = null)
|
||||
|
@ -75,7 +70,8 @@ class Extractor extends Regex
|
|||
if (is_null($tweet)) {
|
||||
$tweet = $this->tweet;
|
||||
}
|
||||
return array(
|
||||
|
||||
return [
|
||||
'hashtags' => $this->extractHashtags($tweet),
|
||||
'urls' => $this->extractURLs($tweet),
|
||||
'mentions' => $this->extractMentionedUsernames($tweet),
|
||||
|
@ -83,13 +79,14 @@ class Extractor extends Regex
|
|||
'hashtags_with_indices' => $this->extractHashtagsWithIndices($tweet),
|
||||
'urls_with_indices' => $this->extractURLsWithIndices($tweet),
|
||||
'mentions_with_indices' => $this->extractMentionedUsernamesWithIndices($tweet),
|
||||
);
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract URLs, @mentions, lists and #hashtag from a given text/tweet.
|
||||
*
|
||||
* @param string $tweet The tweet to extract.
|
||||
*
|
||||
* @return array list of extracted entities
|
||||
*/
|
||||
public function extractEntitiesWithIndices($tweet = null)
|
||||
|
@ -97,12 +94,13 @@ class Extractor extends Regex
|
|||
if (is_null($tweet)) {
|
||||
$tweet = $this->tweet;
|
||||
}
|
||||
$entities = array();
|
||||
$entities = [];
|
||||
$entities = array_merge($entities, $this->extractURLsWithIndices($tweet));
|
||||
$entities = array_merge($entities, $this->extractHashtagsWithIndices($tweet, false));
|
||||
$entities = array_merge($entities, $this->extractMentionsOrListsWithIndices($tweet));
|
||||
$entities = array_merge($entities, $this->extractCashtagsWithIndices($tweet));
|
||||
$entities = $this->removeOverlappingEntities($entities);
|
||||
|
||||
return $entities;
|
||||
}
|
||||
|
||||
|
@ -110,16 +108,18 @@ class Extractor extends Regex
|
|||
* Extracts all the hashtags from the tweet.
|
||||
*
|
||||
* @param string $tweet The tweet to extract.
|
||||
*
|
||||
* @return array The hashtag elements in the tweet.
|
||||
*/
|
||||
public function extractHashtags($tweet = null)
|
||||
{
|
||||
$hashtagsOnly = array();
|
||||
$hashtagsOnly = [];
|
||||
$hashtagsWithIndices = $this->extractHashtagsWithIndices($tweet);
|
||||
|
||||
foreach ($hashtagsWithIndices as $hashtagWithIndex) {
|
||||
$hashtagsOnly[] = $hashtagWithIndex['hashtag'];
|
||||
}
|
||||
|
||||
return $hashtagsOnly;
|
||||
}
|
||||
|
||||
|
@ -127,16 +127,18 @@ class Extractor extends Regex
|
|||
* Extracts all the cashtags from the tweet.
|
||||
*
|
||||
* @param string $tweet The tweet to extract.
|
||||
*
|
||||
* @return array The cashtag elements in the tweet.
|
||||
*/
|
||||
public function extractCashtags($tweet = null)
|
||||
{
|
||||
$cashtagsOnly = array();
|
||||
$cashtagsOnly = [];
|
||||
$cashtagsWithIndices = $this->extractCashtagsWithIndices($tweet);
|
||||
|
||||
foreach ($cashtagsWithIndices as $cashtagWithIndex) {
|
||||
$cashtagsOnly[] = $cashtagWithIndex['cashtag'];
|
||||
}
|
||||
|
||||
return $cashtagsOnly;
|
||||
}
|
||||
|
||||
|
@ -144,16 +146,18 @@ class Extractor extends Regex
|
|||
* Extracts all the URLs from the tweet.
|
||||
*
|
||||
* @param string $tweet The tweet to extract.
|
||||
*
|
||||
* @return array The URL elements in the tweet.
|
||||
*/
|
||||
public function extractURLs($tweet = null)
|
||||
{
|
||||
$urlsOnly = array();
|
||||
$urlsOnly = [];
|
||||
$urlsWithIndices = $this->extractURLsWithIndices($tweet);
|
||||
|
||||
foreach ($urlsWithIndices as $urlWithIndex) {
|
||||
$urlsOnly[] = $urlWithIndex['url'];
|
||||
}
|
||||
|
||||
return $urlsOnly;
|
||||
}
|
||||
|
||||
|
@ -163,20 +167,22 @@ class Extractor extends Regex
|
|||
* A mention is an occurrence of a username anywhere in a tweet.
|
||||
*
|
||||
* @param string $tweet The tweet to extract.
|
||||
*
|
||||
* @return array The usernames elements in the tweet.
|
||||
*/
|
||||
public function extractMentionedScreennames($tweet = null)
|
||||
{
|
||||
$usernamesOnly = array();
|
||||
$usernamesOnly = [];
|
||||
$mentionsWithIndices = $this->extractMentionsOrListsWithIndices($tweet);
|
||||
|
||||
foreach ($mentionsWithIndices as $mentionWithIndex) {
|
||||
$screen_name = mb_strtolower($mentionWithIndex['screen_name']);
|
||||
if (empty($screen_name) OR in_array($screen_name, $usernamesOnly)) {
|
||||
if (empty($screen_name) or in_array($screen_name, $usernamesOnly)) {
|
||||
continue;
|
||||
}
|
||||
$usernamesOnly[] = $screen_name;
|
||||
}
|
||||
|
||||
return $usernamesOnly;
|
||||
}
|
||||
|
||||
|
@ -186,11 +192,13 @@ class Extractor extends Regex
|
|||
* A mention is an occurrence of a username anywhere in a tweet.
|
||||
*
|
||||
* @return array The usernames elements in the tweet.
|
||||
*
|
||||
* @deprecated since version 1.1.0
|
||||
*/
|
||||
public function extractMentionedUsernames($tweet)
|
||||
{
|
||||
$this->tweet = $tweet;
|
||||
|
||||
return $this->extractMentionedScreennames($tweet);
|
||||
}
|
||||
|
||||
|
@ -200,6 +208,7 @@ class Extractor extends Regex
|
|||
* A reply is an occurrence of a username at the beginning of a tweet.
|
||||
*
|
||||
* @param string $tweet The tweet to extract.
|
||||
*
|
||||
* @return array The usernames replied to in a tweet.
|
||||
*/
|
||||
public function extractReplyScreenname($tweet = null)
|
||||
|
@ -208,10 +217,11 @@ class Extractor extends Regex
|
|||
$tweet = $this->tweet;
|
||||
}
|
||||
$matched = preg_match(self::$patterns['valid_reply'], $tweet, $matches);
|
||||
# Check username ending in
|
||||
// Check username ending in
|
||||
if ($matched && preg_match(self::$patterns['end_mention_match'], $matches[2])) {
|
||||
$matched = false;
|
||||
}
|
||||
|
||||
return $matched ? $matches[1] : null;
|
||||
}
|
||||
|
||||
|
@ -221,6 +231,7 @@ class Extractor extends Regex
|
|||
* A reply is an occurrence of a username at the beginning of a tweet.
|
||||
*
|
||||
* @return array The usernames replied to in a tweet.
|
||||
*
|
||||
* @deprecated since version 1.1.0
|
||||
*/
|
||||
public function extractRepliedUsernames()
|
||||
|
@ -232,7 +243,8 @@ class Extractor extends Regex
|
|||
* Extracts all the hashtags and the indices they occur at from the tweet.
|
||||
*
|
||||
* @param string $tweet The tweet to extract.
|
||||
* @param boolean $checkUrlOverlap if true, check if extracted hashtags overlap URLs and remove overlapping ones
|
||||
* @param bool $checkUrlOverlap if true, check if extracted hashtags overlap URLs and remove overlapping ones
|
||||
*
|
||||
* @return array The hashtag elements in the tweet.
|
||||
*/
|
||||
public function extractHashtagsWithIndices($tweet = null, $checkUrlOverlap = true)
|
||||
|
@ -242,14 +254,14 @@ class Extractor extends Regex
|
|||
}
|
||||
|
||||
if (!preg_match('/[##]/iu', $tweet)) {
|
||||
return array();
|
||||
return [];
|
||||
}
|
||||
|
||||
preg_match_all(self::$patterns['valid_hashtag'], $tweet, $matches, PREG_SET_ORDER | PREG_OFFSET_CAPTURE);
|
||||
$tags = array();
|
||||
$tags = [];
|
||||
|
||||
foreach ($matches as $match) {
|
||||
list($all, $before, $hash, $hashtag, $outer) = array_pad($match, 3, array('', 0));
|
||||
list($all, $before, $hash, $hashtag, $outer) = array_pad($match, 3, ['', 0]);
|
||||
$start_position = $hash[1] > 0 ? StringUtils::strlen(substr($tweet, 0, $hash[1])) : $hash[1];
|
||||
$end_position = $start_position + StringUtils::strlen($hash[0].$hashtag[0]);
|
||||
|
||||
|
@ -257,21 +269,21 @@ class Extractor extends Regex
|
|||
continue;
|
||||
}
|
||||
|
||||
$tags[] = array(
|
||||
$tags[] = [
|
||||
'hashtag' => $hashtag[0],
|
||||
'indices' => array($start_position, $end_position)
|
||||
);
|
||||
'indices' => [$start_position, $end_position],
|
||||
];
|
||||
}
|
||||
|
||||
if (!$checkUrlOverlap) {
|
||||
return $tags;
|
||||
}
|
||||
|
||||
# check url overlap
|
||||
// check url overlap
|
||||
$urls = $this->extractURLsWithIndices($tweet);
|
||||
$entities = $this->removeOverlappingEntities(array_merge($tags, $urls));
|
||||
|
||||
$validTags = array();
|
||||
$validTags = [];
|
||||
foreach ($entities as $entity) {
|
||||
if (empty($entity['hashtag'])) {
|
||||
continue;
|
||||
|
@ -286,6 +298,7 @@ class Extractor extends Regex
|
|||
* Extracts all the cashtags and the indices they occur at from the tweet.
|
||||
*
|
||||
* @param string $tweet The tweet to extract.
|
||||
*
|
||||
* @return array The cashtag elements in the tweet.
|
||||
*/
|
||||
public function extractCashtagsWithIndices($tweet = null)
|
||||
|
@ -295,14 +308,14 @@ class Extractor extends Regex
|
|||
}
|
||||
|
||||
if (!preg_match('/\$/iu', $tweet)) {
|
||||
return array();
|
||||
return [];
|
||||
}
|
||||
|
||||
preg_match_all(self::$patterns['valid_cashtag'], $tweet, $matches, PREG_SET_ORDER | PREG_OFFSET_CAPTURE);
|
||||
$tags = array();
|
||||
$tags = [];
|
||||
|
||||
foreach ($matches as $match) {
|
||||
list($all, $before, $dollar, $cash_text, $outer) = array_pad($match, 3, array('', 0));
|
||||
list($all, $before, $dollar, $cash_text, $outer) = array_pad($match, 3, ['', 0]);
|
||||
$start_position = $dollar[1] > 0 ? StringUtils::strlen(substr($tweet, 0, $dollar[1])) : $dollar[1];
|
||||
$end_position = $start_position + StringUtils::strlen($dollar[0].$cash_text[0]);
|
||||
|
||||
|
@ -310,10 +323,10 @@ class Extractor extends Regex
|
|||
continue;
|
||||
}
|
||||
|
||||
$tags[] = array(
|
||||
$tags[] = [
|
||||
'cashtag' => $cash_text[0],
|
||||
'indices' => array($start_position, $end_position)
|
||||
);
|
||||
'indices' => [$start_position, $end_position],
|
||||
];
|
||||
}
|
||||
|
||||
return $tags;
|
||||
|
@ -323,6 +336,7 @@ class Extractor extends Regex
|
|||
* Extracts all the URLs and the indices they occur at from the tweet.
|
||||
*
|
||||
* @param string $tweet The tweet to extract.
|
||||
*
|
||||
* @return array The URLs elements in the tweet.
|
||||
*/
|
||||
public function extractURLsWithIndices($tweet = null)
|
||||
|
@ -333,14 +347,14 @@ class Extractor extends Regex
|
|||
|
||||
$needle = $this->extractURLWithoutProtocol() ? '.' : ':';
|
||||
if (strpos($tweet, $needle) === false) {
|
||||
return array();
|
||||
return [];
|
||||
}
|
||||
|
||||
$urls = array();
|
||||
$urls = [];
|
||||
preg_match_all(self::$patterns['valid_url'], $tweet, $matches, PREG_SET_ORDER | PREG_OFFSET_CAPTURE);
|
||||
|
||||
foreach ($matches as $match) {
|
||||
list($all, $before, $url, $protocol, $domain, $port, $path, $query) = array_pad($match, 8, array(''));
|
||||
list($all, $before, $url, $protocol, $domain, $port, $path, $query) = array_pad($match, 8, ['']);
|
||||
$start_position = $url[1] > 0 ? StringUtils::strlen(substr($tweet, 0, $url[1])) : $url[1];
|
||||
$end_position = $start_position + StringUtils::strlen($url[0]);
|
||||
|
||||
|
@ -367,10 +381,10 @@ class Extractor extends Regex
|
|||
$asciiDomain[0] = preg_replace('/'.preg_quote($domain, '/').'/u', $asciiDomain[0], $url);
|
||||
$ascii_start_position = StringUtils::strpos($domain, $asciiDomain[0], $ascii_end_position);
|
||||
$ascii_end_position = $ascii_start_position + StringUtils::strlen($asciiDomain[0]);
|
||||
$last_url = array(
|
||||
$last_url = [
|
||||
'url' => $asciiDomain[0],
|
||||
'indices' => array($start_position + $ascii_start_position, $start_position + $ascii_end_position),
|
||||
);
|
||||
'indices' => [$start_position + $ascii_start_position, $start_position + $ascii_end_position],
|
||||
];
|
||||
if (!empty($path)
|
||||
|| preg_match(self::$patterns['valid_special_short_domain'], $asciiDomain[0])
|
||||
|| !preg_match(self::$patterns['invalid_short_domain'], $asciiDomain[0])) {
|
||||
|
@ -395,10 +409,10 @@ class Extractor extends Regex
|
|||
$url = $tcoUrlMatches[0];
|
||||
$end_position = $start_position + StringUtils::strlen($url);
|
||||
}
|
||||
$urls[] = array(
|
||||
$urls[] = [
|
||||
'url' => $url,
|
||||
'indices' => array($start_position, $end_position),
|
||||
);
|
||||
'indices' => [$start_position, $end_position],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -409,6 +423,7 @@ class Extractor extends Regex
|
|||
* Extracts all the usernames and the indices they occur at from the tweet.
|
||||
*
|
||||
* @param string $tweet The tweet to extract.
|
||||
*
|
||||
* @return array The username elements in the tweet.
|
||||
*/
|
||||
public function extractMentionedScreennamesWithIndices($tweet = null)
|
||||
|
@ -417,7 +432,7 @@ class Extractor extends Regex
|
|||
$tweet = $this->tweet;
|
||||
}
|
||||
|
||||
$usernamesOnly = array();
|
||||
$usernamesOnly = [];
|
||||
$mentions = $this->extractMentionsOrListsWithIndices($tweet);
|
||||
foreach ($mentions as $mention) {
|
||||
if (isset($mention['list_slug'])) {
|
||||
|
@ -425,6 +440,7 @@ class Extractor extends Regex
|
|||
}
|
||||
$usernamesOnly[] = $mention;
|
||||
}
|
||||
|
||||
return $usernamesOnly;
|
||||
}
|
||||
|
||||
|
@ -432,6 +448,7 @@ class Extractor extends Regex
|
|||
* Extracts all the usernames and the indices they occur at from the tweet.
|
||||
*
|
||||
* @return array The username elements in the tweet.
|
||||
*
|
||||
* @deprecated since version 1.1.0
|
||||
*/
|
||||
public function extractMentionedUsernamesWithIndices()
|
||||
|
@ -443,6 +460,7 @@ class Extractor extends Regex
|
|||
* Extracts all the usernames and the indices they occur at from the tweet.
|
||||
*
|
||||
* @param string $tweet The tweet to extract.
|
||||
*
|
||||
* @return array The username elements in the tweet.
|
||||
*/
|
||||
public function extractMentionsOrListsWithIndices($tweet = null)
|
||||
|
@ -452,21 +470,21 @@ class Extractor extends Regex
|
|||
}
|
||||
|
||||
if (!preg_match('/[@@]/iu', $tweet)) {
|
||||
return array();
|
||||
return [];
|
||||
}
|
||||
|
||||
preg_match_all(self::$patterns['valid_mentions_or_lists'], $tweet, $matches, PREG_SET_ORDER | PREG_OFFSET_CAPTURE);
|
||||
$results = array();
|
||||
$results = [];
|
||||
|
||||
foreach ($matches as $match) {
|
||||
list($all, $before, $at, $username, $list_slug, $outer) = array_pad($match, 6, array('', 0));
|
||||
list($all, $before, $at, $username, $list_slug, $outer) = array_pad($match, 6, ['', 0]);
|
||||
$start_position = $at[1] > 0 ? StringUtils::strlen(substr($tweet, 0, $at[1])) : $at[1];
|
||||
$end_position = $start_position + StringUtils::strlen($at[0]) + StringUtils::strlen($username[0]);
|
||||
$entity = array(
|
||||
$entity = [
|
||||
'screen_name' => $username[0],
|
||||
'list_slug' => $list_slug[0],
|
||||
'indices' => array($start_position, $end_position),
|
||||
);
|
||||
'indices' => [$start_position, $end_position],
|
||||
];
|
||||
|
||||
if (preg_match(self::$patterns['end_mention_match'], $outer[0])) {
|
||||
continue;
|
||||
|
@ -486,6 +504,7 @@ class Extractor extends Regex
|
|||
* Extracts all the usernames and the indices they occur at from the tweet.
|
||||
*
|
||||
* @return array The username elements in the tweet.
|
||||
*
|
||||
* @deprecated since version 1.1.0
|
||||
*/
|
||||
public function extractMentionedUsernamesOrListsWithIndices()
|
||||
|
@ -494,9 +513,10 @@ class Extractor extends Regex
|
|||
}
|
||||
|
||||
/**
|
||||
* setter/getter for extractURLWithoutProtocol
|
||||
* setter/getter for extractURLWithoutProtocol.
|
||||
*
|
||||
* @param bool $flag
|
||||
*
|
||||
* @param boolean $flag
|
||||
* @return Extractor
|
||||
*/
|
||||
public function extractURLWithoutProtocol($flag = null)
|
||||
|
@ -505,6 +525,7 @@ class Extractor extends Regex
|
|||
return $this->extractURLWithoutProtocol;
|
||||
}
|
||||
$this->extractURLWithoutProtocol = (bool) $flag;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
@ -513,12 +534,13 @@ class Extractor extends Regex
|
|||
* This returns a new array with no overlapping entities.
|
||||
*
|
||||
* @param array $entities
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function removeOverlappingEntities($entities)
|
||||
{
|
||||
$result = array();
|
||||
usort($entities, array($this, 'sortEntites'));
|
||||
$result = [];
|
||||
usort($entities, [$this, 'sortEntites']);
|
||||
|
||||
$prev = null;
|
||||
foreach ($entities as $entity) {
|
||||
|
@ -528,14 +550,16 @@ class Extractor extends Regex
|
|||
$prev = $entity;
|
||||
$result[] = $entity;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* sort by entity start index
|
||||
* sort by entity start index.
|
||||
*
|
||||
* @param array $a
|
||||
* @param array $b
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
protected function sortEntites($a, $b)
|
||||
|
@ -543,6 +567,7 @@ class Extractor extends Regex
|
|||
if ($a['indices'][0] == $b['indices'][0]) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return ($a['indices'][0] < $b['indices'][0]) ? -1 : 1;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
|
||||
namespace App\Util\Lexer;
|
||||
|
||||
class Hashtag {
|
||||
|
||||
class Hashtag
|
||||
{
|
||||
public static function getHashtags($status)
|
||||
{
|
||||
$hashtags = false;
|
||||
|
@ -12,13 +12,16 @@ class Hashtag {
|
|||
$res = array_count_values($matches[0]);
|
||||
$hashtags = array_keys($res);
|
||||
}
|
||||
|
||||
return $hashtags;
|
||||
}
|
||||
|
||||
public static function replaceHashtagsWithLinks($status)
|
||||
{
|
||||
$hashtags = self::getHashtags($status);
|
||||
if(!$hashtags) { return false; }
|
||||
if (!$hashtags) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$rendered = $status;
|
||||
|
||||
|
@ -30,7 +33,5 @@ class Hashtag {
|
|||
}
|
||||
|
||||
return $rendered;
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -4,16 +4,12 @@
|
|||
* @author Nick Pope <nick@nickpope.me.uk>
|
||||
* @copyright Copyright © 2010, Nick Pope
|
||||
* @license http://www.apache.org/licenses/LICENSE-2.0 Apache License v2.0
|
||||
* @package Twitter.Text
|
||||
*/
|
||||
|
||||
namespace App\Util\Lexer;
|
||||
|
||||
use App\Util\Lexer\Regex;
|
||||
use App\Util\Lexer\StringUtils;
|
||||
|
||||
/**
|
||||
* Twitter HitHighlighter Class
|
||||
* Twitter HitHighlighter Class.
|
||||
*
|
||||
* Performs "hit highlighting" on tweets that have been auto-linked already.
|
||||
* Useful with the results returned from the search API.
|
||||
|
@ -25,11 +21,9 @@ use App\Util\Lexer\StringUtils;
|
|||
* @author Nick Pope <nick@nickpope.me.uk>
|
||||
* @copyright Copyright © 2010, Nick Pope
|
||||
* @license http://www.apache.org/licenses/LICENSE-2.0 Apache License v2.0
|
||||
* @package Twitter.Text
|
||||
*/
|
||||
class HitHighlighter extends Regex
|
||||
{
|
||||
|
||||
/**
|
||||
* The tag to surround hits with.
|
||||
*
|
||||
|
@ -96,6 +90,7 @@ class HitHighlighter extends Regex
|
|||
public function setTag($v)
|
||||
{
|
||||
$this->tag = $v;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
@ -119,8 +114,8 @@ class HitHighlighter extends Regex
|
|||
return $tweet;
|
||||
}
|
||||
$highlightTweet = '';
|
||||
$tags = array('<' . $this->tag . '>', '</' . $this->tag . '>');
|
||||
# Check whether we can simply replace or whether we need to chunk...
|
||||
$tags = ['<'.$this->tag.'>', '</'.$this->tag.'>'];
|
||||
// Check whether we can simply replace or whether we need to chunk...
|
||||
if (strpos($tweet, '<') === false) {
|
||||
$ti = 0; // tag increment (for added tags)
|
||||
$highlightTweet = $tweet;
|
||||
|
@ -137,12 +132,12 @@ class HitHighlighter extends Regex
|
|||
$chunk_cursor = 0;
|
||||
$offset = 0;
|
||||
$start_in_chunk = false;
|
||||
# Flatten the multidimensional hits array:
|
||||
$hits_flat = array();
|
||||
// Flatten the multidimensional hits array:
|
||||
$hits_flat = [];
|
||||
foreach ($hits as $hit) {
|
||||
$hits_flat = array_merge($hits_flat, $hit);
|
||||
}
|
||||
# Loop over the hit indices:
|
||||
// Loop over the hit indices:
|
||||
for ($index = 0; $index < count($hits_flat); $index++) {
|
||||
$hit = $hits_flat[$index];
|
||||
$tag = $tags[$index % 2];
|
||||
|
@ -169,7 +164,7 @@ class HitHighlighter extends Regex
|
|||
$start_in_chunk = ($index % 2 === 0);
|
||||
$placed = true;
|
||||
}
|
||||
# Ultimate fallback - hits that run off the end get a closing tag:
|
||||
// Ultimate fallback - hits that run off the end get a closing tag:
|
||||
if (!$placed) {
|
||||
$highlightTweet .= $tag;
|
||||
}
|
||||
|
@ -183,6 +178,7 @@ class HitHighlighter extends Regex
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $highlightTweet;
|
||||
}
|
||||
|
||||
|
@ -193,6 +189,7 @@ class HitHighlighter extends Regex
|
|||
* for the highlighting.
|
||||
*
|
||||
* @return string The hit highlighted tweet.
|
||||
*
|
||||
* @deprecated since version 1.1.0
|
||||
*/
|
||||
public function addHitHighlighting(array $hits)
|
||||
|
|
|
@ -6,15 +6,12 @@
|
|||
* @author Takashi Nojima
|
||||
* @copyright Copyright 2014 Mike Cochrane, Nick Pope, Takashi Nojima
|
||||
* @license http://www.apache.org/licenses/LICENSE-2.0 Apache License v2.0
|
||||
* @package Twitter.Text
|
||||
*/
|
||||
|
||||
namespace App\Util\Lexer;
|
||||
|
||||
use App\Util\Lexer\Autolink;
|
||||
|
||||
/**
|
||||
* Twitter LooseAutolink Class
|
||||
* Twitter LooseAutolink Class.
|
||||
*
|
||||
* Parses tweets and generates HTML anchor tags around URLs, usernames,
|
||||
* username/list pairs and hashtags.
|
||||
|
@ -28,18 +25,19 @@ use App\Util\Lexer\Autolink;
|
|||
* @author Takashi Nojima
|
||||
* @copyright Copyright 2014 Mike Cochrane, Nick Pope, Takashi Nojima
|
||||
* @license http://www.apache.org/licenses/LICENSE-2.0 Apache License v2.0
|
||||
* @package Twitter.Text
|
||||
*
|
||||
* @since 1.8.0
|
||||
* @deprecated since version 1.9.0
|
||||
*/
|
||||
class LooseAutolink extends Autolink
|
||||
{
|
||||
|
||||
/**
|
||||
* Auto-link hashtags, URLs, usernames and lists.
|
||||
*
|
||||
* @param string The tweet to be converted
|
||||
*
|
||||
* @return string that auto-link HTML added
|
||||
*
|
||||
* @deprecated since version 1.9.0
|
||||
*/
|
||||
public function autoLink($tweet = null)
|
||||
|
@ -47,6 +45,7 @@ class LooseAutolink extends Autolink
|
|||
if (!is_null($tweet)) {
|
||||
$this->tweet = $tweet;
|
||||
}
|
||||
|
||||
return $this->addLinks();
|
||||
}
|
||||
|
||||
|
@ -62,6 +61,7 @@ class LooseAutolink extends Autolink
|
|||
if (!is_null($tweet)) {
|
||||
$this->tweet = $tweet;
|
||||
}
|
||||
|
||||
return $this->addLinksToUsernamesAndLists();
|
||||
}
|
||||
|
||||
|
@ -76,6 +76,7 @@ class LooseAutolink extends Autolink
|
|||
if (!is_null($tweet)) {
|
||||
$this->tweet = $tweet;
|
||||
}
|
||||
|
||||
return $this->addLinksToHashtags();
|
||||
}
|
||||
|
||||
|
@ -91,6 +92,7 @@ class LooseAutolink extends Autolink
|
|||
if (!is_null($tweet)) {
|
||||
$this->tweet = $tweet;
|
||||
}
|
||||
|
||||
return $this->addLinksToURLs();
|
||||
}
|
||||
|
||||
|
@ -105,6 +107,7 @@ class LooseAutolink extends Autolink
|
|||
if (!is_null($tweet)) {
|
||||
$this->tweet = $tweet;
|
||||
}
|
||||
|
||||
return $this->addLinksToCashtags();
|
||||
}
|
||||
|
||||
|
@ -112,6 +115,7 @@ class LooseAutolink extends Autolink
|
|||
* Adds links to all elements in the tweet.
|
||||
*
|
||||
* @return string The modified tweet.
|
||||
*
|
||||
* @deprecated since version 1.9.0
|
||||
*/
|
||||
public function addLinks()
|
||||
|
@ -123,6 +127,7 @@ class LooseAutolink extends Autolink
|
|||
$this->tweet = $this->addLinksToUsernamesAndLists();
|
||||
$modified = $this->tweet;
|
||||
$this->tweet = $original;
|
||||
|
||||
return $modified;
|
||||
}
|
||||
|
||||
|
@ -135,7 +140,7 @@ class LooseAutolink extends Autolink
|
|||
{
|
||||
return preg_replace_callback(
|
||||
self::$patterns['valid_hashtag'],
|
||||
array($this, '_addLinksToHashtags'),
|
||||
[$this, '_addLinksToHashtags'],
|
||||
$this->tweet
|
||||
);
|
||||
}
|
||||
|
@ -149,7 +154,7 @@ class LooseAutolink extends Autolink
|
|||
{
|
||||
return preg_replace_callback(
|
||||
self::$patterns['valid_cashtag'],
|
||||
array($this, '_addLinksToCashtags'),
|
||||
[$this, '_addLinksToCashtags'],
|
||||
$this->tweet
|
||||
);
|
||||
}
|
||||
|
@ -161,7 +166,7 @@ class LooseAutolink extends Autolink
|
|||
*/
|
||||
public function addLinksToURLs()
|
||||
{
|
||||
return preg_replace_callback(self::$patterns['valid_url'], array($this, '_addLinksToURLs'), $this->tweet);
|
||||
return preg_replace_callback(self::$patterns['valid_url'], [$this, '_addLinksToURLs'], $this->tweet);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -173,7 +178,7 @@ class LooseAutolink extends Autolink
|
|||
{
|
||||
return preg_replace_callback(
|
||||
self::$patterns['valid_mentions_or_lists'],
|
||||
array($this, '_addLinksToUsernamesAndLists'),
|
||||
[$this, '_addLinksToUsernamesAndLists'],
|
||||
$this->tweet
|
||||
);
|
||||
}
|
||||
|
@ -188,6 +193,7 @@ class LooseAutolink extends Autolink
|
|||
* @param string $element The tweet element to wrap.
|
||||
*
|
||||
* @return string The tweet element with a link applied.
|
||||
*
|
||||
* @deprecated since version 1.1.0
|
||||
*/
|
||||
protected function wrap($url, $class, $element)
|
||||
|
@ -197,7 +203,7 @@ class LooseAutolink extends Autolink
|
|||
$link .= ' class="'.$class.'"';
|
||||
}
|
||||
$link .= ' href="'.$url.'"';
|
||||
$rel = array();
|
||||
$rel = [];
|
||||
if ($this->external) {
|
||||
$rel[] = 'external';
|
||||
}
|
||||
|
@ -211,6 +217,7 @@ class LooseAutolink extends Autolink
|
|||
$link .= ' target="'.$this->target.'"';
|
||||
}
|
||||
$link .= '>'.$element.'</a>';
|
||||
|
||||
return $link;
|
||||
}
|
||||
|
||||
|
@ -234,7 +241,7 @@ class LooseAutolink extends Autolink
|
|||
if ($class) {
|
||||
$link .= ' class="'.$class.'"';
|
||||
}
|
||||
$rel = array();
|
||||
$rel = [];
|
||||
if ($this->external) {
|
||||
$rel[] = 'external';
|
||||
}
|
||||
|
@ -248,6 +255,7 @@ class LooseAutolink extends Autolink
|
|||
$link .= ' target="'.$this->target.'"';
|
||||
}
|
||||
$link .= '>'.$element.'</a>';
|
||||
|
||||
return $link;
|
||||
}
|
||||
|
||||
|
@ -255,7 +263,9 @@ class LooseAutolink extends Autolink
|
|||
* Callback used by the method that adds links to hashtags.
|
||||
*
|
||||
* @see addLinksToHashtags()
|
||||
*
|
||||
* @param array $matches The regular expression matches.
|
||||
*
|
||||
* @return string The link-wrapped hashtag.
|
||||
*/
|
||||
protected function _addLinksToHashtags($matches)
|
||||
|
@ -273,6 +283,7 @@ class LooseAutolink extends Autolink
|
|||
$class_hash .= ' rtl';
|
||||
}
|
||||
$replacement .= $this->wrapHash($url, $class_hash, $element);
|
||||
|
||||
return $replacement;
|
||||
}
|
||||
|
||||
|
@ -280,7 +291,9 @@ class LooseAutolink extends Autolink
|
|||
* Callback used by the method that adds links to cashtags.
|
||||
*
|
||||
* @see addLinksToCashtags()
|
||||
*
|
||||
* @param array $matches The regular expression matches.
|
||||
*
|
||||
* @return string The link-wrapped cashtag.
|
||||
*/
|
||||
protected function _addLinksToCashtags($matches)
|
||||
|
@ -294,6 +307,7 @@ class LooseAutolink extends Autolink
|
|||
$element = $cash.$tag;
|
||||
$url = $this->url_base_cash.$tag;
|
||||
$replacement .= $this->wrapHash($url, $this->class_cash, $element);
|
||||
|
||||
return $replacement;
|
||||
}
|
||||
|
||||
|
@ -301,7 +315,9 @@ class LooseAutolink extends Autolink
|
|||
* Callback used by the method that adds links to URLs.
|
||||
*
|
||||
* @see addLinksToURLs()
|
||||
*
|
||||
* @param array $matches The regular expression matches.
|
||||
*
|
||||
* @return string The link-wrapped URL.
|
||||
*/
|
||||
protected function _addLinksToURLs($matches)
|
||||
|
@ -311,6 +327,7 @@ class LooseAutolink extends Autolink
|
|||
if (!$protocol) {
|
||||
return $all;
|
||||
}
|
||||
|
||||
return $before.$this->wrap($url, $this->class_url, $url);
|
||||
}
|
||||
|
||||
|
@ -318,15 +335,17 @@ class LooseAutolink extends Autolink
|
|||
* Callback used by the method that adds links to username/list pairs.
|
||||
*
|
||||
* @see addLinksToUsernamesAndLists()
|
||||
*
|
||||
* @param array $matches The regular expression matches.
|
||||
*
|
||||
* @return string The link-wrapped username/list pair.
|
||||
*/
|
||||
protected function _addLinksToUsernamesAndLists($matches)
|
||||
{
|
||||
list($all, $before, $at, $username, $slash_listname, $after) = array_pad($matches, 6, '');
|
||||
# If $after is not empty, there is an invalid character.
|
||||
// If $after is not empty, there is an invalid character.
|
||||
if (!empty($slash_listname)) {
|
||||
# Replace the list and username
|
||||
// Replace the list and username
|
||||
$element = $username.$slash_listname;
|
||||
$class = $this->class_list;
|
||||
$url = $this->url_base_list.$element;
|
||||
|
@ -334,15 +353,15 @@ class LooseAutolink extends Autolink
|
|||
if (preg_match(self::$patterns['end_mention_match'], $after)) {
|
||||
return $all;
|
||||
}
|
||||
# Replace the username
|
||||
// Replace the username
|
||||
$element = $username;
|
||||
$class = $this->class_user;
|
||||
$url = $this->url_base_user.$element;
|
||||
}
|
||||
# XXX: Due to use of preg_replace_callback() for multiple replacements in a
|
||||
# single tweet and also as only the match is replaced and we have to
|
||||
# use a look-ahead for $after because there is no equivalent for the
|
||||
# $' (dollar apostrophe) global from Ruby, we MUST NOT append $after.
|
||||
// XXX: Due to use of preg_replace_callback() for multiple replacements in a
|
||||
// single tweet and also as only the match is replaced and we have to
|
||||
// use a look-ahead for $after because there is no equivalent for the
|
||||
// $' (dollar apostrophe) global from Ruby, we MUST NOT append $after.
|
||||
return $before.$at.$this->wrap($url, $class, $element);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
|
||||
namespace App\Util\Lexer;
|
||||
|
||||
class Nickname {
|
||||
|
||||
class Nickname
|
||||
{
|
||||
public static function normalizeProfileUrl($url)
|
||||
{
|
||||
if (starts_with($url, 'acct:')) {
|
||||
|
@ -13,6 +13,7 @@ class Nickname {
|
|||
if (!str_contains($url, '@') && filter_var($url, FILTER_VALIDATE_URL)) {
|
||||
$parsed = parse_url($url);
|
||||
$username = str_replace(['/', '\\', '@'], '', $parsed['path']);
|
||||
|
||||
return ['domain' => $parsed['host'], 'username' => $username];
|
||||
}
|
||||
$parts = explode('@', $url);
|
||||
|
@ -34,9 +35,8 @@ class Nickname {
|
|||
} else {
|
||||
$username = $part;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return ['domain' => $domain, 'username' => $username];
|
||||
}
|
||||
|
||||
}
|
|
@ -2,18 +2,20 @@
|
|||
|
||||
namespace App\Util\Lexer;
|
||||
|
||||
class PrettyNumber {
|
||||
|
||||
class PrettyNumber
|
||||
{
|
||||
public static function convert($expression)
|
||||
{
|
||||
$abbrevs = array(12 => "T", 9 => "B", 6 => "M", 3 => "K", 0 => "");
|
||||
$abbrevs = [12 => 'T', 9 => 'B', 6 => 'M', 3 => 'K', 0 => ''];
|
||||
foreach ($abbrevs as $exponent => $abbrev) {
|
||||
if ($expression >= pow(10, $exponent)) {
|
||||
$display_num = $expression / pow(10, $exponent);
|
||||
$num = number_format($display_num, 0).$abbrev;
|
||||
|
||||
return $num;
|
||||
}
|
||||
}
|
||||
|
||||
return $expression;
|
||||
}
|
||||
|
||||
|
@ -28,9 +30,10 @@ class PrettyNumber {
|
|||
$units = $short ?
|
||||
['B', 'k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y'] :
|
||||
['B', 'kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
|
||||
for($i = 0; ($size / 1024) > 0.9; $i++, $size /= 1024) {}
|
||||
for ($i = 0; ($size / 1024) > 0.9; $i++, $size /= 1024) {
|
||||
}
|
||||
$res = round($size, $precision).$units[$i];
|
||||
|
||||
return $res;
|
||||
}
|
||||
|
||||
}
|
|
@ -5,13 +5,12 @@
|
|||
* @author Nick Pope <nick@nickpope.me.uk>
|
||||
* @copyright Copyright © 2010, Mike Cochrane, Nick Pope
|
||||
* @license http://www.apache.org/licenses/LICENSE-2.0 Apache License v2.0
|
||||
* @package Twitter.Text
|
||||
*/
|
||||
|
||||
namespace App\Util\Lexer;
|
||||
|
||||
/**
|
||||
* Twitter Regex Abstract Class
|
||||
* Twitter Regex Abstract Class.
|
||||
*
|
||||
* Used by subclasses that need to parse tweets.
|
||||
*
|
||||
|
@ -23,17 +22,15 @@ namespace App\Util\Lexer;
|
|||
* @author Nick Pope <nick@nickpope.me.uk>
|
||||
* @copyright Copyright © 2010, Mike Cochrane, Nick Pope
|
||||
* @license http://www.apache.org/licenses/LICENSE-2.0 Apache License v2.0
|
||||
* @package Twitter
|
||||
*/
|
||||
abstract class Regex
|
||||
{
|
||||
|
||||
/**
|
||||
* Contains all generated regular expressions.
|
||||
*
|
||||
* @var string The regex patterns.
|
||||
*/
|
||||
protected static $patterns = array();
|
||||
protected static $patterns = [];
|
||||
|
||||
/**
|
||||
* The tweet to be used in parsing. This should be populated by the
|
||||
|
@ -58,99 +55,99 @@ abstract class Regex
|
|||
*/
|
||||
public static function __static()
|
||||
{
|
||||
# Check whether we have initialized the regular expressions:
|
||||
// Check whether we have initialized the regular expressions:
|
||||
static $initialized = false;
|
||||
if ($initialized) {
|
||||
return;
|
||||
}
|
||||
# Get a shorter reference to the regular expression array:
|
||||
// Get a shorter reference to the regular expression array:
|
||||
$re = &self::$patterns;
|
||||
# Initialise local storage arrays:
|
||||
$tmp = array();
|
||||
// Initialise local storage arrays:
|
||||
$tmp = [];
|
||||
|
||||
# Expression to match whitespace characters.
|
||||
#
|
||||
# 0x0009-0x000D Cc # <control-0009>..<control-000D>
|
||||
# 0x0020 Zs # SPACE
|
||||
# 0x0085 Cc # <control-0085>
|
||||
# 0x00A0 Zs # NO-BREAK SPACE
|
||||
# 0x1680 Zs # OGHAM SPACE MARK
|
||||
# 0x180E Zs # MONGOLIAN VOWEL SEPARATOR
|
||||
# 0x2000-0x200A Zs # EN QUAD..HAIR SPACE
|
||||
# 0x2028 Zl # LINE SEPARATOR
|
||||
# 0x2029 Zp # PARAGRAPH SEPARATOR
|
||||
# 0x202F Zs # NARROW NO-BREAK SPACE
|
||||
# 0x205F Zs # MEDIUM MATHEMATICAL SPACE
|
||||
# 0x3000 Zs # IDEOGRAPHIC SPACE
|
||||
// Expression to match whitespace characters.
|
||||
//
|
||||
// 0x0009-0x000D Cc # <control-0009>..<control-000D>
|
||||
// 0x0020 Zs # SPACE
|
||||
// 0x0085 Cc # <control-0085>
|
||||
// 0x00A0 Zs # NO-BREAK SPACE
|
||||
// 0x1680 Zs # OGHAM SPACE MARK
|
||||
// 0x180E Zs # MONGOLIAN VOWEL SEPARATOR
|
||||
// 0x2000-0x200A Zs # EN QUAD..HAIR SPACE
|
||||
// 0x2028 Zl # LINE SEPARATOR
|
||||
// 0x2029 Zp # PARAGRAPH SEPARATOR
|
||||
// 0x202F Zs # NARROW NO-BREAK SPACE
|
||||
// 0x205F Zs # MEDIUM MATHEMATICAL SPACE
|
||||
// 0x3000 Zs # IDEOGRAPHIC SPACE
|
||||
$tmp['spaces'] = '\x{0009}-\x{000D}\x{0020}\x{0085}\x{00a0}\x{1680}\x{180E}\x{2000}-\x{200a}\x{2028}\x{2029}\x{202f}\x{205f}\x{3000}';
|
||||
|
||||
# Invalid Characters:
|
||||
# 0xFFFE,0xFEFF # BOM
|
||||
# 0xFFFF # Special
|
||||
# 0x202A-0x202E # Directional change
|
||||
// Invalid Characters:
|
||||
// 0xFFFE,0xFEFF # BOM
|
||||
// 0xFFFF # Special
|
||||
// 0x202A-0x202E # Directional change
|
||||
$tmp['invalid_characters'] = '\x{202a}-\x{202e}\x{feff}\x{fffe}\x{ffff}';
|
||||
|
||||
# Expression to match at and hash sign characters:
|
||||
// Expression to match at and hash sign characters:
|
||||
$tmp['at_signs'] = '@@';
|
||||
$tmp['hash_signs'] = '##';
|
||||
|
||||
# Expression to match latin accented characters.
|
||||
#
|
||||
# 0x00C0-0x00D6
|
||||
# 0x00D8-0x00F6
|
||||
# 0x00F8-0x00FF
|
||||
# 0x0100-0x024f
|
||||
# 0x0253-0x0254
|
||||
# 0x0256-0x0257
|
||||
# 0x0259
|
||||
# 0x025b
|
||||
# 0x0263
|
||||
# 0x0268
|
||||
# 0x026f
|
||||
# 0x0272
|
||||
# 0x0289
|
||||
# 0x028b
|
||||
# 0x02bb
|
||||
# 0x0300-0x036f
|
||||
# 0x1e00-0x1eff
|
||||
#
|
||||
# Excludes 0x00D7 - multiplication sign (confusable with 'x').
|
||||
# Excludes 0x00F7 - division sign.
|
||||
// Expression to match latin accented characters.
|
||||
//
|
||||
// 0x00C0-0x00D6
|
||||
// 0x00D8-0x00F6
|
||||
// 0x00F8-0x00FF
|
||||
// 0x0100-0x024f
|
||||
// 0x0253-0x0254
|
||||
// 0x0256-0x0257
|
||||
// 0x0259
|
||||
// 0x025b
|
||||
// 0x0263
|
||||
// 0x0268
|
||||
// 0x026f
|
||||
// 0x0272
|
||||
// 0x0289
|
||||
// 0x028b
|
||||
// 0x02bb
|
||||
// 0x0300-0x036f
|
||||
// 0x1e00-0x1eff
|
||||
//
|
||||
// Excludes 0x00D7 - multiplication sign (confusable with 'x').
|
||||
// Excludes 0x00F7 - division sign.
|
||||
$tmp['latin_accents'] = '\x{00c0}-\x{00d6}\x{00d8}-\x{00f6}\x{00f8}-\x{00ff}';
|
||||
$tmp['latin_accents'] .= '\x{0100}-\x{024f}\x{0253}-\x{0254}\x{0256}-\x{0257}';
|
||||
$tmp['latin_accents'] .= '\x{0259}\x{025b}\x{0263}\x{0268}\x{026f}\x{0272}\x{0289}\x{028b}\x{02bb}\x{0300}-\x{036f}\x{1e00}-\x{1eff}';
|
||||
|
||||
# Expression to match RTL characters.
|
||||
#
|
||||
# 0x0600-0x06FF Arabic
|
||||
# 0x0750-0x077F Arabic Supplement
|
||||
# 0x08A0-0x08FF Arabic Extended-A
|
||||
# 0x0590-0x05FF Hebrew
|
||||
# 0xFB50-0xFDFF Arabic Presentation Forms-A
|
||||
# 0xFE70-0xFEFF Arabic Presentation Forms-B
|
||||
// Expression to match RTL characters.
|
||||
//
|
||||
// 0x0600-0x06FF Arabic
|
||||
// 0x0750-0x077F Arabic Supplement
|
||||
// 0x08A0-0x08FF Arabic Extended-A
|
||||
// 0x0590-0x05FF Hebrew
|
||||
// 0xFB50-0xFDFF Arabic Presentation Forms-A
|
||||
// 0xFE70-0xFEFF Arabic Presentation Forms-B
|
||||
$tmp['rtl_chars'] = '\x{0600}-\x{06ff}\x{0750}-\x{077f}\x{08a0}-\x{08ff}\x{0590}-\x{05ff}\x{fb50}-\x{fdff}\x{fe70}-\x{feff}';
|
||||
|
||||
$tmp['hashtag_letters'] = '\p{L}\p{M}';
|
||||
$tmp['hashtag_numerals'] = '\p{Nd}';
|
||||
# Hashtag special chars
|
||||
#
|
||||
# _ underscore
|
||||
# 0x200c ZERO WIDTH NON-JOINER (ZWNJ)
|
||||
# 0x200d ZERO WIDTH JOINER (ZWJ)
|
||||
# 0xa67e CYRILLIC KAVYKA
|
||||
# 0x05be HEBREW PUNCTUATION MAQAF
|
||||
# 0x05f3 HEBREW PUNCTUATION GERESH
|
||||
# 0x05f4 HEBREW PUNCTUATION GERSHAYIM
|
||||
# 0xff5e FULLWIDTH TILDE
|
||||
# 0x301c WAVE DASH
|
||||
# 0x309b KATAKANA-HIRAGANA VOICED SOUND MARK
|
||||
# 0x309c KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK
|
||||
# 0x30a0 KATAKANA-HIRAGANA DOUBLE HYPHEN
|
||||
# 0x30fb KATAKANA MIDDLE DOT
|
||||
# 0x3003 DITTO MARK
|
||||
# 0x0f0b TIBETAN MARK INTERSYLLABIC TSHEG
|
||||
# 0x0f0c TIBETAN MARK DELIMITER TSHEG BSTAR
|
||||
# 0x00b7 MIDDLE DOT
|
||||
// Hashtag special chars
|
||||
//
|
||||
// _ underscore
|
||||
// 0x200c ZERO WIDTH NON-JOINER (ZWNJ)
|
||||
// 0x200d ZERO WIDTH JOINER (ZWJ)
|
||||
// 0xa67e CYRILLIC KAVYKA
|
||||
// 0x05be HEBREW PUNCTUATION MAQAF
|
||||
// 0x05f3 HEBREW PUNCTUATION GERESH
|
||||
// 0x05f4 HEBREW PUNCTUATION GERSHAYIM
|
||||
// 0xff5e FULLWIDTH TILDE
|
||||
// 0x301c WAVE DASH
|
||||
// 0x309b KATAKANA-HIRAGANA VOICED SOUND MARK
|
||||
// 0x309c KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK
|
||||
// 0x30a0 KATAKANA-HIRAGANA DOUBLE HYPHEN
|
||||
// 0x30fb KATAKANA MIDDLE DOT
|
||||
// 0x3003 DITTO MARK
|
||||
// 0x0f0b TIBETAN MARK INTERSYLLABIC TSHEG
|
||||
// 0x0f0c TIBETAN MARK DELIMITER TSHEG BSTAR
|
||||
// 0x00b7 MIDDLE DOT
|
||||
$tmp['hashtag_special_chars'] = '_\x{200c}\x{200d}\x{a67e}\x{05be}\x{05f3}\x{05f4}\x{ff5e}\x{301c}\x{309b}\x{309c}\x{30a0}\x{30fb}\x{3003}\x{0f0b}\x{0f0c}\x{00b7}';
|
||||
$tmp['hashtag_letters_numerals_set'] = '['.$tmp['hashtag_letters'].$tmp['hashtag_numerals'].$tmp['hashtag_special_chars'].']';
|
||||
$tmp['hashtag_letters_set'] = '['.$tmp['hashtag_letters'].']';
|
||||
|
@ -160,15 +157,15 @@ abstract class Regex
|
|||
$re['valid_hashtag'] = '/'.$tmp['hashtag'].'(?=(.*|$))/iu';
|
||||
$re['end_hashtag_match'] = '/\A(?:['.$tmp['hash_signs'].']|:\/\/)/u';
|
||||
|
||||
# XXX: PHP doesn't have Ruby's $' (dollar apostrophe) so we have to capture
|
||||
# $after in the following regular expression. Note that we only use a
|
||||
# look-ahead capture here and don't append $after when we return.
|
||||
// XXX: PHP doesn't have Ruby's $' (dollar apostrophe) so we have to capture
|
||||
// $after in the following regular expression. Note that we only use a
|
||||
// look-ahead capture here and don't append $after when we return.
|
||||
$tmp['valid_mention_preceding_chars'] = '([^a-zA-Z0-9_!#\$%&*@@\/]|^|(?:^|[^a-z0-9_+~.-])RT:?)';
|
||||
$re['valid_mentions_or_lists'] = '/'.$tmp['valid_mention_preceding_chars'].'(['.$tmp['at_signs'].'])([a-z0-9_]{1,20})(\/[a-z][a-z0-9_\-]{0,24})?(?=(.*|$))/iu';
|
||||
$re['valid_reply'] = '/^(?:['.$tmp['spaces'].'])*['.$tmp['at_signs'].']([a-z0-9_]{1,20})(?=(.*|$))/iu';
|
||||
$re['end_mention_match'] = '/\A(?:['.$tmp['at_signs'].']|['.$tmp['latin_accents'].']|:\/\/)/iu';
|
||||
|
||||
# URL related hash regex collection
|
||||
// URL related hash regex collection
|
||||
|
||||
$tmp['valid_url_preceding_chars'] = '(?:[^A-Z0-9_@@\$##\.'.$tmp['invalid_characters'].']|^)';
|
||||
|
||||
|
@ -204,13 +201,13 @@ abstract class Regex
|
|||
.'|(?:' // domain + ccTLD + '/'
|
||||
.$tmp['valid_domain_name'].$tmp['valid_ccTLD'].'(?=\/)' // e.g. t.co/
|
||||
.')';
|
||||
# Used by the extractor:
|
||||
// Used by the extractor:
|
||||
$re['valid_ascii_domain'] = '/'.$tmp['valid_subdomain'].'*'.$tmp['valid_domain_name'].'(?:'.$tmp['valid_gTLD'].'|'.$tmp['valid_ccTLD'].'|'.$tmp['valid_punycode'].')/iu';
|
||||
|
||||
# Used by the extractor for stricter t.co URL extraction:
|
||||
// Used by the extractor for stricter t.co URL extraction:
|
||||
$re['valid_tco_url'] = '/^https?:\/\/t\.co\/[a-z0-9]+/iu';
|
||||
|
||||
# Used by the extractor to filter out unwanted URLs:
|
||||
// Used by the extractor to filter out unwanted URLs:
|
||||
$re['invalid_short_domain'] = '/\A'.$tmp['valid_domain_name'].$tmp['valid_ccTLD'].'\Z/iu';
|
||||
$re['valid_special_short_domain'] = '/\A'.$tmp['valid_domain_name'].$tmp['valid_special_ccTLD'].'\Z/iu';
|
||||
$re['invalid_url_without_protocol_preceding_chars'] = '/[\-_.\/]\z/iu';
|
||||
|
@ -218,10 +215,10 @@ abstract class Regex
|
|||
$tmp['valid_port_number'] = '[0-9]+';
|
||||
|
||||
$tmp['valid_general_url_path_chars'] = '[a-z\p{Cyrillic}0-9!\*;:=\+\,\.\$\/%#\[\]\-_~&|@'.$tmp['latin_accents'].']';
|
||||
# Allow URL paths to contain up to two nested levels of balanced parentheses:
|
||||
# 1. Used in Wikipedia URLs, e.g. /Primer_(film)
|
||||
# 2. Used in IIS sessions, e.g. /S(dfd346)/
|
||||
# 3. Used in Rdio URLs like /track/We_Up_(Album_Version_(Edited))/
|
||||
// Allow URL paths to contain up to two nested levels of balanced parentheses:
|
||||
// 1. Used in Wikipedia URLs, e.g. /Primer_(film)
|
||||
// 2. Used in IIS sessions, e.g. /S(dfd346)/
|
||||
// 3. Used in Rdio URLs like /track/We_Up_(Album_Version_(Edited))/
|
||||
$tmp['valid_url_balanced_parens'] = '(?:\('
|
||||
.'(?:'.$tmp['valid_general_url_path_chars'].'+'
|
||||
.'|'
|
||||
|
@ -233,8 +230,8 @@ abstract class Regex
|
|||
.')'
|
||||
.')'
|
||||
.'\))';
|
||||
# Valid end-of-path characters (so /foo. does not gobble the period).
|
||||
# 1. Allow =&# for empty URL parameters and other URL-join artifacts.
|
||||
// Valid end-of-path characters (so /foo. does not gobble the period).
|
||||
// 1. Allow =&# for empty URL parameters and other URL-join artifacts.
|
||||
$tmp['valid_url_path_ending_chars'] = '[a-z\p{Cyrillic}0-9=_#\/\+\-'.$tmp['latin_accents'].']|(?:'.$tmp['valid_url_balanced_parens'].')';
|
||||
$tmp['valid_url_path'] = '(?:(?:'
|
||||
.$tmp['valid_general_url_path_chars'].'*(?:'
|
||||
|
@ -246,14 +243,14 @@ abstract class Regex
|
|||
$tmp['valid_url_query_chars'] = '[a-z0-9!?\*\'\(\);:&=\+\$\/%#\[\]\-_\.,~|@]';
|
||||
$tmp['valid_url_query_ending_chars'] = '[a-z0-9_&=#\/\-]';
|
||||
|
||||
$re['valid_url'] = '/(?:' # $1 Complete match (preg_match() already matches everything.)
|
||||
. '(' . $tmp['valid_url_preceding_chars'] . ')' # $2 Preceding characters
|
||||
. '(' # $3 Complete URL
|
||||
. '(https?:\/\/)?' # $4 Protocol (optional)
|
||||
. '(' . $tmp['valid_domain'] . ')' # $5 Domain(s)
|
||||
. '(?::(' . $tmp['valid_port_number'] . '))?' # $6 Port number (optional)
|
||||
. '(\/' . $tmp['valid_url_path'] . '*)?' # $7 URL Path
|
||||
. '(\?' . $tmp['valid_url_query_chars'] . '*' . $tmp['valid_url_query_ending_chars'] . ')?' # $8 Query String
|
||||
$re['valid_url'] = '/(?:' // $1 Complete match (preg_match() already matches everything.)
|
||||
.'('.$tmp['valid_url_preceding_chars'].')' // $2 Preceding characters
|
||||
.'(' // $3 Complete URL
|
||||
.'(https?:\/\/)?' // $4 Protocol (optional)
|
||||
.'('.$tmp['valid_domain'].')' // $5 Domain(s)
|
||||
.'(?::('.$tmp['valid_port_number'].'))?' // $6 Port number (optional)
|
||||
.'(\/'.$tmp['valid_url_path'].'*)?' // $7 URL Path
|
||||
.'(\?'.$tmp['valid_url_query_chars'].'*'.$tmp['valid_url_query_ending_chars'].')?' // $8 Query String
|
||||
.')'
|
||||
.')/iux';
|
||||
|
||||
|
@ -262,47 +259,47 @@ abstract class Regex
|
|||
$re['valid_cashtag'] = '/(^|['.$tmp['spaces'].'])(['.$tmp['cash_signs'].'])('.$tmp['cashtag'].')(?=($|\s|[[:punct:]]))/iu';
|
||||
$re['end_cashtag_match'] = '/\A(?:['.$tmp['cash_signs'].']|:\/\/)/u';
|
||||
|
||||
# These URL validation pattern strings are based on the ABNF from RFC 3986
|
||||
// These URL validation pattern strings are based on the ABNF from RFC 3986
|
||||
$tmp['validate_url_unreserved'] = '[a-z\p{Cyrillic}0-9\-._~]';
|
||||
$tmp['validate_url_pct_encoded'] = '(?:%[0-9a-f]{2})';
|
||||
$tmp['validate_url_sub_delims'] = '[!$&\'()*+,;=]';
|
||||
$tmp['validate_url_pchar'] = '(?:' . $tmp['validate_url_unreserved'] . '|' . $tmp['validate_url_pct_encoded'] . '|' . $tmp['validate_url_sub_delims'] . '|[:\|@])'; #/iox
|
||||
$tmp['validate_url_pchar'] = '(?:'.$tmp['validate_url_unreserved'].'|'.$tmp['validate_url_pct_encoded'].'|'.$tmp['validate_url_sub_delims'].'|[:\|@])'; ///iox
|
||||
|
||||
$tmp['validate_url_userinfo'] = '(?:' . $tmp['validate_url_unreserved'] . '|' . $tmp['validate_url_pct_encoded'] . '|' . $tmp['validate_url_sub_delims'] . '|:)*'; #/iox
|
||||
$tmp['validate_url_userinfo'] = '(?:'.$tmp['validate_url_unreserved'].'|'.$tmp['validate_url_pct_encoded'].'|'.$tmp['validate_url_sub_delims'].'|:)*'; ///iox
|
||||
|
||||
$tmp['validate_url_dec_octet'] = '(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])'; #/i
|
||||
$tmp['validate_url_ipv4'] = '(?:' . $tmp['validate_url_dec_octet'] . '(?:\.' . $tmp['validate_url_dec_octet'] . '){3})'; #/iox
|
||||
# Punting on real IPv6 validation for now
|
||||
$tmp['validate_url_ipv6'] = '(?:\[[a-f0-9:\.]+\])'; #/i
|
||||
# Also punting on IPvFuture for now
|
||||
$tmp['validate_url_ip'] = '(?:' . $tmp['validate_url_ipv4'] . '|' . $tmp['validate_url_ipv6'] . ')'; #/iox
|
||||
# This is more strict than the rfc specifies
|
||||
$tmp['validate_url_subdomain_segment'] = '(?:[a-z0-9](?:[a-z0-9_\-]*[a-z0-9])?)'; #/i
|
||||
$tmp['validate_url_domain_segment'] = '(?:[a-z0-9](?:[a-z0-9\-]*[a-z0-9])?)'; #/i
|
||||
$tmp['validate_url_domain_tld'] = '(?:[a-z](?:[a-z0-9\-]*[a-z0-9])?)'; #/i
|
||||
$tmp['validate_url_domain'] = '(?:(?:' . $tmp['validate_url_subdomain_segment'] . '\.)*(?:' . $tmp['validate_url_domain_segment'] . '\.)' . $tmp['validate_url_domain_tld'] . ')'; #/iox
|
||||
$tmp['validate_url_dec_octet'] = '(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])'; ///i
|
||||
$tmp['validate_url_ipv4'] = '(?:'.$tmp['validate_url_dec_octet'].'(?:\.'.$tmp['validate_url_dec_octet'].'){3})'; ///iox
|
||||
// Punting on real IPv6 validation for now
|
||||
$tmp['validate_url_ipv6'] = '(?:\[[a-f0-9:\.]+\])'; ///i
|
||||
// Also punting on IPvFuture for now
|
||||
$tmp['validate_url_ip'] = '(?:'.$tmp['validate_url_ipv4'].'|'.$tmp['validate_url_ipv6'].')'; ///iox
|
||||
// This is more strict than the rfc specifies
|
||||
$tmp['validate_url_subdomain_segment'] = '(?:[a-z0-9](?:[a-z0-9_\-]*[a-z0-9])?)'; ///i
|
||||
$tmp['validate_url_domain_segment'] = '(?:[a-z0-9](?:[a-z0-9\-]*[a-z0-9])?)'; ///i
|
||||
$tmp['validate_url_domain_tld'] = '(?:[a-z](?:[a-z0-9\-]*[a-z0-9])?)'; ///i
|
||||
$tmp['validate_url_domain'] = '(?:(?:'.$tmp['validate_url_subdomain_segment'].'\.)*(?:'.$tmp['validate_url_domain_segment'].'\.)'.$tmp['validate_url_domain_tld'].')'; ///iox
|
||||
|
||||
$tmp['validate_url_host'] = '(?:' . $tmp['validate_url_ip'] . '|' . $tmp['validate_url_domain'] . ')'; #/iox
|
||||
# Unencoded internationalized domains - this doesn't check for invalid UTF-8 sequences
|
||||
$tmp['validate_url_unicode_subdomain_segment'] = '(?:(?:[a-z0-9]|[^\x00-\x7f])(?:(?:[a-z0-9_\-]|[^\x00-\x7f])*(?:[a-z0-9]|[^\x00-\x7f]))?)'; #/ix
|
||||
$tmp['validate_url_unicode_domain_segment'] = '(?:(?:[a-z0-9]|[^\x00-\x7f])(?:(?:[a-z0-9\-]|[^\x00-\x7f])*(?:[a-z0-9]|[^\x00-\x7f]))?)'; #/ix
|
||||
$tmp['validate_url_unicode_domain_tld'] = '(?:(?:[a-z]|[^\x00-\x7f])(?:(?:[a-z0-9\-]|[^\x00-\x7f])*(?:[a-z0-9]|[^\x00-\x7f]))?)'; #/ix
|
||||
$tmp['validate_url_unicode_domain'] = '(?:(?:' . $tmp['validate_url_unicode_subdomain_segment'] . '\.)*(?:' . $tmp['validate_url_unicode_domain_segment'] . '\.)' . $tmp['validate_url_unicode_domain_tld'] . ')'; #/iox
|
||||
$tmp['validate_url_host'] = '(?:'.$tmp['validate_url_ip'].'|'.$tmp['validate_url_domain'].')'; ///iox
|
||||
// Unencoded internationalized domains - this doesn't check for invalid UTF-8 sequences
|
||||
$tmp['validate_url_unicode_subdomain_segment'] = '(?:(?:[a-z0-9]|[^\x00-\x7f])(?:(?:[a-z0-9_\-]|[^\x00-\x7f])*(?:[a-z0-9]|[^\x00-\x7f]))?)'; ///ix
|
||||
$tmp['validate_url_unicode_domain_segment'] = '(?:(?:[a-z0-9]|[^\x00-\x7f])(?:(?:[a-z0-9\-]|[^\x00-\x7f])*(?:[a-z0-9]|[^\x00-\x7f]))?)'; ///ix
|
||||
$tmp['validate_url_unicode_domain_tld'] = '(?:(?:[a-z]|[^\x00-\x7f])(?:(?:[a-z0-9\-]|[^\x00-\x7f])*(?:[a-z0-9]|[^\x00-\x7f]))?)'; ///ix
|
||||
$tmp['validate_url_unicode_domain'] = '(?:(?:'.$tmp['validate_url_unicode_subdomain_segment'].'\.)*(?:'.$tmp['validate_url_unicode_domain_segment'].'\.)'.$tmp['validate_url_unicode_domain_tld'].')'; ///iox
|
||||
|
||||
$tmp['validate_url_unicode_host'] = '(?:' . $tmp['validate_url_ip'] . '|' . $tmp['validate_url_unicode_domain'] . ')'; #/iox
|
||||
$tmp['validate_url_unicode_host'] = '(?:'.$tmp['validate_url_ip'].'|'.$tmp['validate_url_unicode_domain'].')'; ///iox
|
||||
|
||||
$tmp['validate_url_port'] = '[0-9]{1,5}';
|
||||
|
||||
$re['validate_url_unicode_authority'] = '/'
|
||||
. '(?:(' . $tmp['validate_url_userinfo'] . ')@)?' # $1 userinfo
|
||||
. '(' . $tmp['validate_url_unicode_host'] . ')' # $2 host
|
||||
. '(?::(' . $tmp['validate_url_port'] . '))?' # $3 port
|
||||
.'(?:('.$tmp['validate_url_userinfo'].')@)?' // $1 userinfo
|
||||
.'('.$tmp['validate_url_unicode_host'].')' // $2 host
|
||||
.'(?::('.$tmp['validate_url_port'].'))?' // $3 port
|
||||
.'/iux';
|
||||
|
||||
$re['validate_url_authority'] = '/'
|
||||
. '(?:(' . $tmp['validate_url_userinfo'] . ')@)?' # $1 userinfo
|
||||
. '(' . $tmp['validate_url_host'] . ')' # $2 host
|
||||
. '(?::(' . $tmp['validate_url_port'] . '))?' # $3 port
|
||||
.'(?:('.$tmp['validate_url_userinfo'].')@)?' // $1 userinfo
|
||||
.'('.$tmp['validate_url_host'].')' // $2 host
|
||||
.'(?::('.$tmp['validate_url_port'].'))?' // $3 port
|
||||
.'/ix';
|
||||
|
||||
$re['validate_url_scheme'] = '/(?:[a-z][a-z0-9+\-.]*)/i';
|
||||
|
@ -310,28 +307,28 @@ abstract class Regex
|
|||
$re['validate_url_query'] = '/('.$tmp['validate_url_pchar'].'|\/|\?)*/iu';
|
||||
$re['validate_url_fragment'] = '/('.$tmp['validate_url_pchar'].'|\/|\?)*/iu';
|
||||
|
||||
# Modified version of RFC 3986 Appendix B
|
||||
$re['validate_url_unencoded'] = '/^' # Full URL
|
||||
// Modified version of RFC 3986 Appendix B
|
||||
$re['validate_url_unencoded'] = '/^' // Full URL
|
||||
.'(?:'
|
||||
. '([^:\/?#]+):\/\/' # $1 Scheme
|
||||
.'([^:\/?#]+):\/\/' // $1 Scheme
|
||||
.')?'
|
||||
. '([^\/?#]*)' # $2 Authority
|
||||
. '([^?#]*)' # $3 Path
|
||||
.'([^\/?#]*)' // $2 Authority
|
||||
.'([^?#]*)' // $3 Path
|
||||
.'(?:'
|
||||
. '\?([^#]*)' # $4 Query
|
||||
.'\?([^#]*)' // $4 Query
|
||||
.')?'
|
||||
.'(?:'
|
||||
. '\#(.*)' # $5 Fragment
|
||||
.'\#(.*)' // $5 Fragment
|
||||
.')?$/iux';
|
||||
|
||||
$re['invalid_characters'] = '/['.$tmp['invalid_characters'].']/u';
|
||||
|
||||
$re['rtl_chars'] = '/['.$tmp['rtl_chars'].']/iu';
|
||||
|
||||
# Flag that initialization is complete:
|
||||
// Flag that initialization is complete:
|
||||
$initialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
# Cause regular expressions to be initialized as soon as this file is loaded:
|
||||
// Cause regular expressions to be initialized as soon as this file is loaded:
|
||||
Regex::__static();
|
||||
|
|
|
@ -2,170 +2,169 @@
|
|||
|
||||
namespace App\Util\Lexer;
|
||||
|
||||
class RestrictedNames {
|
||||
|
||||
static $blacklist = [
|
||||
"about",
|
||||
"abuse",
|
||||
"administrator",
|
||||
"app",
|
||||
"autoconfig",
|
||||
"blog",
|
||||
"broadcasthost",
|
||||
"community",
|
||||
"contact",
|
||||
"contact-us",
|
||||
"contact_us",
|
||||
"copyright",
|
||||
"d",
|
||||
"dashboard",
|
||||
"dev",
|
||||
"developer",
|
||||
"developers",
|
||||
"discover",
|
||||
"discovers",
|
||||
"doc",
|
||||
"docs",
|
||||
"download",
|
||||
"domainadmin",
|
||||
"domainadministrator",
|
||||
"email",
|
||||
"errors",
|
||||
"events",
|
||||
"example",
|
||||
"faq",
|
||||
"faqs",
|
||||
"features",
|
||||
"ftp",
|
||||
"guest",
|
||||
"guests",
|
||||
"help",
|
||||
"hostmaster",
|
||||
"hostmaster",
|
||||
"image",
|
||||
"images",
|
||||
"imap",
|
||||
"img",
|
||||
"info",
|
||||
"info",
|
||||
"is",
|
||||
"isatap",
|
||||
"it",
|
||||
"localdomain",
|
||||
"localhost",
|
||||
"mail",
|
||||
"mailer-daemon",
|
||||
"mailerdaemon",
|
||||
"marketing",
|
||||
"me",
|
||||
"media",
|
||||
"mis",
|
||||
"mx",
|
||||
"new",
|
||||
"news",
|
||||
"news",
|
||||
"no-reply",
|
||||
"nobody",
|
||||
"noc",
|
||||
"noreply",
|
||||
"ns0",
|
||||
"ns1",
|
||||
"ns2",
|
||||
"ns3",
|
||||
"ns4",
|
||||
"ns5",
|
||||
"ns6",
|
||||
"ns7",
|
||||
"ns8",
|
||||
"ns9",
|
||||
"owner",
|
||||
"pop",
|
||||
"pop3",
|
||||
"postmaster",
|
||||
"pricing",
|
||||
"privacy",
|
||||
"root",
|
||||
"sales",
|
||||
"security",
|
||||
"signin",
|
||||
"signout",
|
||||
"smtp",
|
||||
"src",
|
||||
"ssladmin",
|
||||
"ssladministrator",
|
||||
"sslwebmaster",
|
||||
"status",
|
||||
"support",
|
||||
"support",
|
||||
"sys",
|
||||
"sysadmin",
|
||||
"system",
|
||||
"terms",
|
||||
"tutorial",
|
||||
"tutorials",
|
||||
"usenet",
|
||||
"uucp",
|
||||
"webmaster",
|
||||
"wpad",
|
||||
"www"
|
||||
class RestrictedNames
|
||||
{
|
||||
public static $blacklist = [
|
||||
'about',
|
||||
'abuse',
|
||||
'administrator',
|
||||
'app',
|
||||
'autoconfig',
|
||||
'blog',
|
||||
'broadcasthost',
|
||||
'community',
|
||||
'contact',
|
||||
'contact-us',
|
||||
'contact_us',
|
||||
'copyright',
|
||||
'd',
|
||||
'dashboard',
|
||||
'dev',
|
||||
'developer',
|
||||
'developers',
|
||||
'discover',
|
||||
'discovers',
|
||||
'doc',
|
||||
'docs',
|
||||
'download',
|
||||
'domainadmin',
|
||||
'domainadministrator',
|
||||
'email',
|
||||
'errors',
|
||||
'events',
|
||||
'example',
|
||||
'faq',
|
||||
'faqs',
|
||||
'features',
|
||||
'ftp',
|
||||
'guest',
|
||||
'guests',
|
||||
'help',
|
||||
'hostmaster',
|
||||
'hostmaster',
|
||||
'image',
|
||||
'images',
|
||||
'imap',
|
||||
'img',
|
||||
'info',
|
||||
'info',
|
||||
'is',
|
||||
'isatap',
|
||||
'it',
|
||||
'localdomain',
|
||||
'localhost',
|
||||
'mail',
|
||||
'mailer-daemon',
|
||||
'mailerdaemon',
|
||||
'marketing',
|
||||
'me',
|
||||
'media',
|
||||
'mis',
|
||||
'mx',
|
||||
'new',
|
||||
'news',
|
||||
'news',
|
||||
'no-reply',
|
||||
'nobody',
|
||||
'noc',
|
||||
'noreply',
|
||||
'ns0',
|
||||
'ns1',
|
||||
'ns2',
|
||||
'ns3',
|
||||
'ns4',
|
||||
'ns5',
|
||||
'ns6',
|
||||
'ns7',
|
||||
'ns8',
|
||||
'ns9',
|
||||
'owner',
|
||||
'pop',
|
||||
'pop3',
|
||||
'postmaster',
|
||||
'pricing',
|
||||
'privacy',
|
||||
'root',
|
||||
'sales',
|
||||
'security',
|
||||
'signin',
|
||||
'signout',
|
||||
'smtp',
|
||||
'src',
|
||||
'ssladmin',
|
||||
'ssladministrator',
|
||||
'sslwebmaster',
|
||||
'status',
|
||||
'support',
|
||||
'support',
|
||||
'sys',
|
||||
'sysadmin',
|
||||
'system',
|
||||
'terms',
|
||||
'tutorial',
|
||||
'tutorials',
|
||||
'usenet',
|
||||
'uucp',
|
||||
'webmaster',
|
||||
'wpad',
|
||||
'www',
|
||||
];
|
||||
|
||||
static $reserved = [
|
||||
public static $reserved = [
|
||||
// Reserved for instance admin
|
||||
"admin",
|
||||
'admin',
|
||||
|
||||
// Static Assets
|
||||
"assets",
|
||||
"storage",
|
||||
'assets',
|
||||
'storage',
|
||||
|
||||
// Laravel Horizon
|
||||
"horizon",
|
||||
'horizon',
|
||||
|
||||
// Reserved routes
|
||||
"account",
|
||||
"api",
|
||||
"auth",
|
||||
"css",
|
||||
"c",
|
||||
"i",
|
||||
"dashboard",
|
||||
"deck",
|
||||
"discover",
|
||||
"docs",
|
||||
"fonts",
|
||||
"home",
|
||||
"img",
|
||||
"js",
|
||||
"login",
|
||||
"logout",
|
||||
"media",
|
||||
"p",
|
||||
"password",
|
||||
"report",
|
||||
"reports",
|
||||
"search",
|
||||
"settings",
|
||||
"statuses",
|
||||
"site",
|
||||
"sites",
|
||||
"timeline",
|
||||
"timelines",
|
||||
"tour",
|
||||
"user",
|
||||
"users",
|
||||
"vendor",
|
||||
"400",
|
||||
"401",
|
||||
"403",
|
||||
"404",
|
||||
"500",
|
||||
"503",
|
||||
"504",
|
||||
'account',
|
||||
'api',
|
||||
'auth',
|
||||
'css',
|
||||
'c',
|
||||
'i',
|
||||
'dashboard',
|
||||
'deck',
|
||||
'discover',
|
||||
'docs',
|
||||
'fonts',
|
||||
'home',
|
||||
'img',
|
||||
'js',
|
||||
'login',
|
||||
'logout',
|
||||
'media',
|
||||
'p',
|
||||
'password',
|
||||
'report',
|
||||
'reports',
|
||||
'search',
|
||||
'settings',
|
||||
'statuses',
|
||||
'site',
|
||||
'sites',
|
||||
'timeline',
|
||||
'timelines',
|
||||
'tour',
|
||||
'user',
|
||||
'users',
|
||||
'vendor',
|
||||
'400',
|
||||
'401',
|
||||
'403',
|
||||
'404',
|
||||
'500',
|
||||
'503',
|
||||
'504',
|
||||
];
|
||||
|
||||
public static function get()
|
||||
{
|
||||
|
||||
$reserved = $blacklist = [];
|
||||
|
||||
if (true == config('pixelfed.restricted_names.use_blacklist')) {
|
||||
|
@ -175,7 +174,7 @@ class RestrictedNames {
|
|||
if (true == config('pixelfed.restricted_names.reserved_routes')) {
|
||||
$reserved = self::$reserved;
|
||||
}
|
||||
|
||||
return array_merge($blacklist, $reserved);
|
||||
}
|
||||
|
||||
}
|
|
@ -4,29 +4,27 @@
|
|||
* @author Takashi Nojima
|
||||
* @copyright Copyright 2014, Takashi Nojima
|
||||
* @license http://www.apache.org/licenses/LICENSE-2.0 Apache License v2.0
|
||||
* @package Twitter.Text
|
||||
*/
|
||||
|
||||
namespace App\Util\Lexer;
|
||||
|
||||
/**
|
||||
* String utility
|
||||
* String utility.
|
||||
*
|
||||
* @author Takashi Nojima
|
||||
* @copyright Copyright 2014, Takashi Nojima
|
||||
* @license http://www.apache.org/licenses/LICENSE-2.0 Apache License v2.0
|
||||
* @package Twitter
|
||||
*/
|
||||
class StringUtils
|
||||
{
|
||||
|
||||
/**
|
||||
* alias of mb_substr
|
||||
* alias of mb_substr.
|
||||
*
|
||||
* @param string $str
|
||||
* @param integer $start
|
||||
* @param integer $length
|
||||
* @param int $start
|
||||
* @param int $length
|
||||
* @param string $encoding
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function substr($str, $start, $length = null, $encoding = 'UTF-8')
|
||||
|
@ -35,15 +33,17 @@ class StringUtils
|
|||
// for PHP <= 5.4.7
|
||||
$length = mb_strlen($str, $encoding);
|
||||
}
|
||||
|
||||
return mb_substr($str, $start, $length, $encoding);
|
||||
}
|
||||
|
||||
/**
|
||||
* alias of mb_strlen
|
||||
* alias of mb_strlen.
|
||||
*
|
||||
* @param string $str
|
||||
* @param string $encoding
|
||||
* @return integer
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public static function strlen($str, $encoding = 'UTF-8')
|
||||
{
|
||||
|
@ -51,13 +51,14 @@ class StringUtils
|
|||
}
|
||||
|
||||
/**
|
||||
* alias of mb_strpos
|
||||
* alias of mb_strpos.
|
||||
*
|
||||
* @param string $haystack
|
||||
* @param string $needle
|
||||
* @param integer $offset
|
||||
* @param int $offset
|
||||
* @param string $encoding
|
||||
* @return integer
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public static function strpos($haystack, $needle, $offset = 0, $encoding = 'UTF-8')
|
||||
{
|
||||
|
@ -97,8 +98,10 @@ class StringUtils
|
|||
|
||||
$suffixOffset = $start + $length;
|
||||
$suffixLength = $string_length - $start - $length;
|
||||
|
||||
return static::substr($string, 0, $start, $encoding).$replacement.static::substr($string, $suffixOffset, $suffixLength, $encoding);
|
||||
}
|
||||
|
||||
return (is_null($length) === true) ? substr_replace($string, $replacement, $start) : substr_replace($string, $replacement, $start, $length);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,17 +4,12 @@
|
|||
* @author Nick Pope <nick@nickpope.me.uk>
|
||||
* @copyright Copyright © 2010, Nick Pope
|
||||
* @license http://www.apache.org/licenses/LICENSE-2.0 Apache License v2.0
|
||||
* @package Twitter.Text
|
||||
*/
|
||||
|
||||
namespace App\Util\Lexer;
|
||||
|
||||
use App\Util\Lexer\Regex;
|
||||
use App\Util\Lexer\Extractor;
|
||||
use App\Util\Lexer\StringUtils;
|
||||
|
||||
/**
|
||||
* Twitter Validator Class
|
||||
* Twitter Validator Class.
|
||||
*
|
||||
* Performs "validation" on tweets.
|
||||
*
|
||||
|
@ -25,11 +20,9 @@ use App\Util\Lexer\StringUtils;
|
|||
* @author Nick Pope <nick@nickpope.me.uk>
|
||||
* @copyright Copyright © 2010, Nick Pope
|
||||
* @license http://www.apache.org/licenses/LICENSE-2.0 Apache License v2.0
|
||||
* @package Twitter.Text
|
||||
*/
|
||||
class Validator extends Regex
|
||||
{
|
||||
|
||||
/**
|
||||
* The maximum length of a tweet.
|
||||
*
|
||||
|
@ -38,21 +31,20 @@ class Validator extends Regex
|
|||
const MAX_LENGTH = 140;
|
||||
|
||||
/**
|
||||
* The length of a short URL beginning with http:
|
||||
* The length of a short URL beginning with http:.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $short_url_length = 23;
|
||||
|
||||
/**
|
||||
* The length of a short URL beginning with http:
|
||||
* The length of a short URL beginning with http:.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $short_url_length_https = 23;
|
||||
|
||||
/**
|
||||
*
|
||||
* @var Extractor
|
||||
*/
|
||||
protected $extractor = null;
|
||||
|
@ -87,10 +79,12 @@ class Validator extends Regex
|
|||
}
|
||||
|
||||
/**
|
||||
* Setup short URL length from Twitter API /help/configuration response
|
||||
* Setup short URL length from Twitter API /help/configuration response.
|
||||
*
|
||||
* @param mixed $config
|
||||
*
|
||||
* @return Validator
|
||||
*
|
||||
* @link https://dev.twitter.com/docs/api/1/get/help/configuration
|
||||
*/
|
||||
public function setConfiguration($config)
|
||||
|
@ -117,19 +111,21 @@ class Validator extends Regex
|
|||
}
|
||||
|
||||
/**
|
||||
* Set the length of a short URL beginning with http:
|
||||
* Set the length of a short URL beginning with http:.
|
||||
*
|
||||
* @param mixed $length
|
||||
*
|
||||
* @return Validator
|
||||
*/
|
||||
public function setShortUrlLength($length)
|
||||
{
|
||||
$this->short_url_length = intval($length);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the length of a short URL beginning with http:
|
||||
* Get the length of a short URL beginning with http:.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
|
@ -139,19 +135,21 @@ class Validator extends Regex
|
|||
}
|
||||
|
||||
/**
|
||||
* Set the length of a short URL beginning with https:
|
||||
* Set the length of a short URL beginning with https:.
|
||||
*
|
||||
* @param mixed $length
|
||||
*
|
||||
* @return Validator
|
||||
*/
|
||||
public function setShortUrlLengthHttps($length)
|
||||
{
|
||||
$this->short_url_length_https = intval($length);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the length of a short URL beginning with https:
|
||||
* Get the length of a short URL beginning with https:.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
|
@ -164,7 +162,8 @@ class Validator extends Regex
|
|||
* Check whether a tweet is valid.
|
||||
*
|
||||
* @param string $tweet The tweet to validate.
|
||||
* @return boolean Whether the tweet is valid.
|
||||
*
|
||||
* @return bool Whether the tweet is valid.
|
||||
*/
|
||||
public function isValidTweetText($tweet = null)
|
||||
{
|
||||
|
@ -181,13 +180,15 @@ class Validator extends Regex
|
|||
if (preg_match(self::$patterns['invalid_characters'], $tweet)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether a tweet is valid.
|
||||
*
|
||||
* @return boolean Whether the tweet is valid.
|
||||
* @return bool Whether the tweet is valid.
|
||||
*
|
||||
* @deprecated since version 1.1.0
|
||||
*/
|
||||
public function validateTweet()
|
||||
|
@ -199,7 +200,8 @@ class Validator extends Regex
|
|||
* Check whether a username is valid.
|
||||
*
|
||||
* @param string $username The username to validate.
|
||||
* @return boolean Whether the username is valid.
|
||||
*
|
||||
* @return bool Whether the username is valid.
|
||||
*/
|
||||
public function isValidUsername($username = null)
|
||||
{
|
||||
|
@ -211,13 +213,15 @@ class Validator extends Regex
|
|||
return false;
|
||||
}
|
||||
$extracted = $this->extractor->extractMentionedScreennames($username);
|
||||
|
||||
return count($extracted) === 1 && $extracted[0] === substr($username, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether a username is valid.
|
||||
*
|
||||
* @return boolean Whether the username is valid.
|
||||
* @return bool Whether the username is valid.
|
||||
*
|
||||
* @deprecated since version 1.1.0
|
||||
*/
|
||||
public function validateUsername()
|
||||
|
@ -229,7 +233,8 @@ class Validator extends Regex
|
|||
* Check whether a list is valid.
|
||||
*
|
||||
* @param string $list The list name to validate.
|
||||
* @return boolean Whether the list is valid.
|
||||
*
|
||||
* @return bool Whether the list is valid.
|
||||
*/
|
||||
public function isValidList($list = null)
|
||||
{
|
||||
|
@ -242,13 +247,15 @@ class Validator extends Regex
|
|||
}
|
||||
preg_match(self::$patterns['valid_mentions_or_lists'], $list, $matches);
|
||||
$matches = array_pad($matches, 5, '');
|
||||
|
||||
return isset($matches) && $matches[1] === '' && $matches[4] && !empty($matches[4]) && $matches[5] === '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether a list is valid.
|
||||
*
|
||||
* @return boolean Whether the list is valid.
|
||||
* @return bool Whether the list is valid.
|
||||
*
|
||||
* @deprecated since version 1.1.0
|
||||
*/
|
||||
public function validateList()
|
||||
|
@ -260,7 +267,8 @@ class Validator extends Regex
|
|||
* Check whether a hashtag is valid.
|
||||
*
|
||||
* @param string $hashtag The hashtag to validate.
|
||||
* @return boolean Whether the hashtag is valid.
|
||||
*
|
||||
* @return bool Whether the hashtag is valid.
|
||||
*/
|
||||
public function isValidHashtag($hashtag = null)
|
||||
{
|
||||
|
@ -272,13 +280,15 @@ class Validator extends Regex
|
|||
return false;
|
||||
}
|
||||
$extracted = $this->extractor->extractHashtags($hashtag);
|
||||
|
||||
return count($extracted) === 1 && $extracted[0] === substr($hashtag, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether a hashtag is valid.
|
||||
*
|
||||
* @return boolean Whether the hashtag is valid.
|
||||
* @return bool Whether the hashtag is valid.
|
||||
*
|
||||
* @deprecated since version 1.1.0
|
||||
*/
|
||||
public function validateHashtag()
|
||||
|
@ -290,10 +300,10 @@ class Validator extends Regex
|
|||
* Check whether a URL is valid.
|
||||
*
|
||||
* @param string $url The url to validate.
|
||||
* @param boolean $unicode_domains Consider the domain to be unicode.
|
||||
* @param boolean $require_protocol Require a protocol for valid domain?
|
||||
* @param bool $unicode_domains Consider the domain to be unicode.
|
||||
* @param bool $require_protocol Require a protocol for valid domain?
|
||||
*
|
||||
* @return boolean Whether the URL is valid.
|
||||
* @return bool Whether the URL is valid.
|
||||
*/
|
||||
public function isValidURL($url = null, $unicode_domains = true, $require_protocol = true)
|
||||
{
|
||||
|
@ -310,25 +320,27 @@ class Validator extends Regex
|
|||
return false;
|
||||
}
|
||||
list($scheme, $authority, $path, $query, $fragment) = array_pad($matches, 5, '');
|
||||
# Check scheme, path, query, fragment:
|
||||
// Check scheme, path, query, fragment:
|
||||
if (($require_protocol && !(
|
||||
self::isValidMatch($scheme, self::$patterns['validate_url_scheme']) && preg_match('/^https?$/i', $scheme))
|
||||
) || !self::isValidMatch($path, self::$patterns['validate_url_path']) || !self::isValidMatch($query, self::$patterns['validate_url_query'], true)
|
||||
|| !self::isValidMatch($fragment, self::$patterns['validate_url_fragment'], true)) {
|
||||
return false;
|
||||
}
|
||||
# Check authority:
|
||||
// Check authority:
|
||||
$authority_pattern = $unicode_domains ? 'validate_url_unicode_authority' : 'validate_url_authority';
|
||||
|
||||
return self::isValidMatch($authority, self::$patterns[$authority_pattern]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether a URL is valid.
|
||||
*
|
||||
* @param boolean $unicode_domains Consider the domain to be unicode.
|
||||
* @param boolean $require_protocol Require a protocol for valid domain?
|
||||
* @param bool $unicode_domains Consider the domain to be unicode.
|
||||
* @param bool $require_protocol Require a protocol for valid domain?
|
||||
*
|
||||
* @return bool Whether the URL is valid.
|
||||
*
|
||||
* @return boolean Whether the URL is valid.
|
||||
* @deprecated since version 1.1.0
|
||||
*/
|
||||
public function validateURL($unicode_domains = true, $require_protocol = true)
|
||||
|
@ -340,6 +352,7 @@ class Validator extends Regex
|
|||
* Determines the length of a tweet. Takes shortening of URLs into account.
|
||||
*
|
||||
* @param string $tweet The tweet to validate.
|
||||
*
|
||||
* @return int the length of a tweet.
|
||||
*/
|
||||
public function getTweetLength($tweet = null)
|
||||
|
@ -353,6 +366,7 @@ class Validator extends Regex
|
|||
$length += $x['indices'][0] - $x['indices'][1];
|
||||
$length += stripos($x['url'], 'https://') === 0 ? $this->short_url_length_https : $this->short_url_length;
|
||||
}
|
||||
|
||||
return $length;
|
||||
}
|
||||
|
||||
|
@ -360,6 +374,7 @@ class Validator extends Regex
|
|||
* Determines the length of a tweet. Takes shortening of URLs into account.
|
||||
*
|
||||
* @return int the length of a tweet.
|
||||
*
|
||||
* @deprecated since version 1.1.0
|
||||
*/
|
||||
public function getLength()
|
||||
|
@ -372,15 +387,15 @@ class Validator extends Regex
|
|||
*
|
||||
* @param string $string The subject string to test.
|
||||
* @param string $pattern The pattern to match against.
|
||||
* @param boolean $optional Whether a match is compulsory or not.
|
||||
* @param bool $optional Whether a match is compulsory or not.
|
||||
*
|
||||
* @return boolean Whether an exact match was found.
|
||||
* @return bool Whether an exact match was found.
|
||||
*/
|
||||
protected static function isValidMatch($string, $pattern, $optional = false)
|
||||
{
|
||||
$found = preg_match($pattern, $string, $matches);
|
||||
if (!$optional) {
|
||||
return (($string || $string === '') && $found && $matches[0] === $string);
|
||||
return ($string || $string === '') && $found && $matches[0] === $string;
|
||||
} else {
|
||||
return !(($string || $string === '') && (!$found || $matches[0] !== $string));
|
||||
}
|
||||
|
|
|
@ -2,19 +2,18 @@
|
|||
|
||||
namespace App\Util\Media;
|
||||
|
||||
use Storage;
|
||||
use App\Media;
|
||||
use Image as Intervention;
|
||||
use Storage;
|
||||
|
||||
class Image {
|
||||
|
||||
class Image
|
||||
{
|
||||
public $square;
|
||||
public $landscape;
|
||||
public $portrait;
|
||||
public $thumbnail;
|
||||
public $orientation;
|
||||
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
ini_set('memory_limit', config('pixelfed.memory_limit', '1024M'));
|
||||
|
@ -24,7 +23,7 @@ class Image {
|
|||
$this->portrait = $this->orientations()['portrait'];
|
||||
$this->thumbnail = [
|
||||
'width' => 293,
|
||||
'height' => 293
|
||||
'height' => 293,
|
||||
];
|
||||
$this->orientation = null;
|
||||
}
|
||||
|
@ -34,16 +33,16 @@ class Image {
|
|||
return [
|
||||
'square' => [
|
||||
'width' => 1080,
|
||||
'height' => 1080
|
||||
'height' => 1080,
|
||||
],
|
||||
'landscape' => [
|
||||
'width' => 1920,
|
||||
'height' => 1080
|
||||
'height' => 1080,
|
||||
],
|
||||
'portrait' => [
|
||||
'width' => 1080,
|
||||
'height' => 1350
|
||||
]
|
||||
'height' => 1350,
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
|
@ -55,7 +54,7 @@ class Image {
|
|||
if ($thumbnail) {
|
||||
return [
|
||||
'dimensions' => $this->thumbnail,
|
||||
'orientation' => 'thumbnail'
|
||||
'orientation' => 'thumbnail',
|
||||
];
|
||||
}
|
||||
|
||||
|
@ -64,9 +63,10 @@ class Image {
|
|||
$orientation = $aspect === 1 ? 'square' :
|
||||
($aspect > 1 ? 'landscape' : 'portrait');
|
||||
$this->orientation = $orientation;
|
||||
|
||||
return [
|
||||
'dimensions' => $this->orientations()[$orientation],
|
||||
'orientation' => $orientation
|
||||
'orientation' => $orientation,
|
||||
];
|
||||
}
|
||||
|
||||
|
@ -75,7 +75,6 @@ class Image {
|
|||
$basePath = storage_path('app/'.$media->media_path);
|
||||
|
||||
$this->handleResizeImage($media);
|
||||
return;
|
||||
}
|
||||
|
||||
public function resizeThumbnail(Media $media)
|
||||
|
@ -83,7 +82,6 @@ class Image {
|
|||
$basePath = storage_path('app/'.$media->media_path);
|
||||
|
||||
$this->handleThumbnailImage($media);
|
||||
return;
|
||||
}
|
||||
|
||||
public function handleResizeImage(Media $media)
|
||||
|
@ -103,8 +101,7 @@ class Image {
|
|||
$ratio = $this->getAspectRatio($file, $thumbnail);
|
||||
$aspect = $ratio['dimensions'];
|
||||
$orientation = $ratio['orientation'];
|
||||
if($media->mime === 'image/gif' && !$thumbnail)
|
||||
{
|
||||
if ($media->mime === 'image/gif' && !$thumbnail) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -132,13 +129,11 @@ class Image {
|
|||
}
|
||||
|
||||
$media->save();
|
||||
|
||||
} catch (Exception $e) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public function setBaseName($basePath, $thumbnail = false, $extension)
|
||||
public function setBaseName($basePath, $thumbnail, $extension)
|
||||
{
|
||||
$png = false;
|
||||
$path = explode('.', $basePath);
|
||||
|
@ -148,5 +143,4 @@ class Image {
|
|||
|
||||
return ['path' => $basePath, 'png' => $png];
|
||||
}
|
||||
|
||||
}
|
|
@ -2,11 +2,8 @@
|
|||
|
||||
namespace App\Util\Webfinger;
|
||||
|
||||
use App\User;
|
||||
use App\Util\Lexer\Nickname;
|
||||
|
||||
class Webfinger {
|
||||
|
||||
class Webfinger
|
||||
{
|
||||
public $user;
|
||||
public $subject;
|
||||
public $aliases;
|
||||
|
@ -16,8 +13,8 @@ class Webfinger {
|
|||
{
|
||||
$this->user = $user;
|
||||
$this->subject = '';
|
||||
$this->aliases = array();
|
||||
$this->links = array();
|
||||
$this->aliases = [];
|
||||
$this->links = [];
|
||||
}
|
||||
|
||||
public function setSubject()
|
||||
|
@ -26,6 +23,7 @@ class Webfinger {
|
|||
$username = $this->user->username;
|
||||
|
||||
$this->subject = 'acct:'.$username.'@'.$host;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
@ -33,8 +31,9 @@ class Webfinger {
|
|||
{
|
||||
$this->aliases = [
|
||||
$this->user->url(),
|
||||
$this->user->permalink()
|
||||
$this->user->permalink(),
|
||||
];
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
@ -46,19 +45,20 @@ class Webfinger {
|
|||
[
|
||||
'rel' => 'http://webfinger.net/rel/profile-page',
|
||||
'type' => 'text/html',
|
||||
'href' => $user->url()
|
||||
'href' => $user->url(),
|
||||
],
|
||||
[
|
||||
'rel' => 'http://schemas.google.com/g/2010#updates-from',
|
||||
'type' => 'application/atom+xml',
|
||||
'href' => $user->permalink('.atom')
|
||||
'href' => $user->permalink('.atom'),
|
||||
],
|
||||
[
|
||||
'rel' => 'self',
|
||||
'type' => 'application/activity+json',
|
||||
'href' => $user->permalink()
|
||||
]
|
||||
'href' => $user->permalink(),
|
||||
],
|
||||
];
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
@ -71,10 +71,7 @@ class Webfinger {
|
|||
return [
|
||||
'subject' => $this->subject,
|
||||
'aliases' => $this->aliases,
|
||||
'links' => $this->links
|
||||
'links' => $this->links,
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
|
@ -2,18 +2,17 @@
|
|||
|
||||
namespace App\Util\Webfinger;
|
||||
|
||||
use App\User;
|
||||
use App\Util\Lexer\Nickname;
|
||||
|
||||
class WebfingerUrl {
|
||||
|
||||
class WebfingerUrl
|
||||
{
|
||||
public static function generateWebfingerUrl($url)
|
||||
{
|
||||
$url = Nickname::normalizeProfileUrl($url);
|
||||
$domain = $url['domain'];
|
||||
$username = $url['username'];
|
||||
$path = "https://{$domain}/.well-known/webfinger?resource={$username}@{$domain}";
|
||||
|
||||
return $path;
|
||||
}
|
||||
|
||||
}
|
|
@ -36,7 +36,7 @@ return [
|
|||
'driver' => 'file', // redis, file, pdo, custom
|
||||
'path' => storage_path('debugbar'), // For file driver
|
||||
'connection' => null, // Leave null for default connection (Redis/PDO)
|
||||
'provider' => '' // Instance of StorageInterface for custom driver
|
||||
'provider' => '', // Instance of StorageInterface for custom driver
|
||||
],
|
||||
|
||||
/*
|
||||
|
@ -148,19 +148,19 @@ return [
|
|||
'hints' => true, // Show hints for common mistakes
|
||||
],
|
||||
'mail' => [
|
||||
'full_log' => false
|
||||
'full_log' => false,
|
||||
],
|
||||
'views' => [
|
||||
'data' => false, //Note: Can slow down the application, because the data can be quite large..
|
||||
],
|
||||
'route' => [
|
||||
'label' => true // show complete route on bar
|
||||
'label' => true, // show complete route on bar
|
||||
],
|
||||
'logs' => [
|
||||
'file' => null
|
||||
'file' => null,
|
||||
],
|
||||
'cache' => [
|
||||
'values' => true // collect cache values
|
||||
'values' => true, // collect cache values
|
||||
],
|
||||
],
|
||||
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue