diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md index 4f9f4c480..e7e75cc9f 100644 --- a/.github/ISSUE_TEMPLATE.md +++ b/.github/ISSUE_TEMPLATE.md @@ -1,11 +1,13 @@ ### For Feature Requests + Desired Feature: ### For Bug Reports -PHP Version: -MySQL Version: +* BookStack Version: +* PHP Version: +* MySQL Version: -Expected Behavior: +##### Expected Behavior -Actual Behavior: +##### Actual Behavior diff --git a/.travis.yml b/.travis.yml index e2eb5f511..0ad753ced 100644 --- a/.travis.yml +++ b/.travis.yml @@ -17,9 +17,7 @@ addons: before_script: - mysql -u root -e 'create database `bookstack-test`;' - - composer config -g github-oauth.github.com $GITHUB_ACCESS_TOKEN - phpenv config-rm xdebug.ini - - composer self-update - composer dump-autoload --no-interaction - composer install --prefer-dist --no-interaction - php artisan clear-compiled -n diff --git a/app/Exceptions/Handler.php b/app/Exceptions/Handler.php index c64f0cd1f..5260eb6cd 100644 --- a/app/Exceptions/Handler.php +++ b/app/Exceptions/Handler.php @@ -3,9 +3,9 @@ namespace BookStack\Exceptions; use Exception; -use Illuminate\Contracts\Validation\ValidationException; +use Illuminate\Auth\AuthenticationException; +use Illuminate\Validation\ValidationException; use Illuminate\Database\Eloquent\ModelNotFoundException; -use PhpSpec\Exception\Example\ErrorException; use Symfony\Component\HttpKernel\Exception\HttpException; use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler; use Illuminate\Auth\Access\AuthorizationException; diff --git a/app/Http/Controllers/BookController.php b/app/Http/Controllers/BookController.php index 57ac486d5..408192ff9 100644 --- a/app/Http/Controllers/BookController.php +++ b/app/Http/Controllers/BookController.php @@ -208,7 +208,7 @@ class BookController extends Controller } // Update permissions on changed models - $this->entityRepo->buildJointPermissions($updatedModels); + if (count($updatedModels) === 0) $this->entityRepo->buildJointPermissions($updatedModels); return redirect($book->getUrl()); } diff --git a/app/Http/Controllers/Controller.php b/app/Http/Controllers/Controller.php index 2b6c88fe0..733d5416b 100644 --- a/app/Http/Controllers/Controller.php +++ b/app/Http/Controllers/Controller.php @@ -4,7 +4,7 @@ namespace BookStack\Http\Controllers; use BookStack\Ownable; use Illuminate\Foundation\Bus\DispatchesJobs; -use Illuminate\Http\Exception\HttpResponseException; +use Illuminate\Http\Exceptions\HttpResponseException; use Illuminate\Http\Request; use Illuminate\Routing\Controller as BaseController; use Illuminate\Foundation\Validation\ValidatesRequests; diff --git a/app/Http/Controllers/PageController.php b/app/Http/Controllers/PageController.php index 6ed9fc30c..4ed10d61e 100644 --- a/app/Http/Controllers/PageController.php +++ b/app/Http/Controllers/PageController.php @@ -158,13 +158,16 @@ class PageController extends Controller $this->checkOwnablePermission('page-view', $page); + $pageContent = $this->entityRepo->renderPage($page); $sidebarTree = $this->entityRepo->getBookChildren($page->book); - $pageNav = $this->entityRepo->getPageNav($page); + $pageNav = $this->entityRepo->getPageNav($pageContent); Views::add($page); $this->setPageTitle($page->getShortName()); - return view('pages/show', ['page' => $page, 'book' => $page->book, - 'current' => $page, 'sidebarTree' => $sidebarTree, 'pageNav' => $pageNav]); + return view('pages/show', [ + 'page' => $page,'book' => $page->book, + 'current' => $page, 'sidebarTree' => $sidebarTree, + 'pageNav' => $pageNav, 'pageContent' => $pageContent]); } /** @@ -430,6 +433,7 @@ class PageController extends Controller { $page = $this->entityRepo->getBySlug('page', $pageSlug, $bookSlug); $pdfContent = $this->exportService->pageToPdf($page); +// return $pdfContent; return response()->make($pdfContent, 200, [ 'Content-Type' => 'application/octet-stream', 'Content-Disposition' => 'attachment; filename="' . $pageSlug . '.pdf' diff --git a/app/Http/Controllers/UserController.php b/app/Http/Controllers/UserController.php index b5184c40a..c98d5f87e 100644 --- a/app/Http/Controllers/UserController.php +++ b/app/Http/Controllers/UserController.php @@ -1,13 +1,8 @@ - 'min:2', 'email' => 'min:2|email|unique:users,email,' . $id, 'password' => 'min:5|required_with:password_confirm', - 'password-confirm' => 'same:password|required_with:password' + 'password-confirm' => 'same:password|required_with:password', + 'setting' => 'array' ]); $user = $this->user->findOrFail($id); @@ -175,6 +171,13 @@ class UserController extends Controller $user->external_auth_id = $request->get('external_auth_id'); } + // Save an user-specific settings + if ($request->has('setting')) { + foreach ($request->get('setting') as $key => $value) { + setting()->putUser($user, $key, $value); + } + } + $user->save(); session()->flash('success', trans('settings.users_edit_success')); diff --git a/app/Http/Kernel.php b/app/Http/Kernel.php index f1d95f5c0..c55cc9ab8 100644 --- a/app/Http/Kernel.php +++ b/app/Http/Kernel.php @@ -1,6 +1,4 @@ - [ 'throttle:60,1', diff --git a/app/Http/Middleware/Localization.php b/app/Http/Middleware/Localization.php new file mode 100644 index 000000000..31cb5d9a2 --- /dev/null +++ b/app/Http/Middleware/Localization.php @@ -0,0 +1,23 @@ +getUser(user(), 'language', $defaultLang); + app()->setLocale($locale); + Carbon::setLocale($locale); + return $next($request); + } +} diff --git a/app/Http/Middleware/RedirectIfAuthenticated.php b/app/Http/Middleware/RedirectIfAuthenticated.php index 2b3c64695..c27df7af4 100644 --- a/app/Http/Middleware/RedirectIfAuthenticated.php +++ b/app/Http/Middleware/RedirectIfAuthenticated.php @@ -1,6 +1,4 @@ -getMimeType(), $imageMimes); }); - - Carbon::setLocale(config('app.locale')); } /** diff --git a/app/Repos/EntityRepo.php b/app/Repos/EntityRepo.php index 0515a4cd4..f1428735c 100644 --- a/app/Repos/EntityRepo.php +++ b/app/Repos/EntityRepo.php @@ -139,7 +139,7 @@ class EntityRepo */ public function getById($type, $id, $allowDrafts = false) { - return $this->entityQuery($type, $allowDrafts)->findOrFail($id); + return $this->entityQuery($type, $allowDrafts)->find($id); } /** @@ -318,15 +318,15 @@ class EntityRepo */ public function getBookChildren(Book $book, $filterDrafts = false) { - $q = $this->permissionService->bookChildrenQuery($book->id, $filterDrafts); + $q = $this->permissionService->bookChildrenQuery($book->id, $filterDrafts)->get(); $entities = []; $parents = []; $tree = []; foreach ($q as $index => $rawEntity) { - if ($rawEntity->entity_type === 'Bookstack\\Page') { + if ($rawEntity->entity_type === 'BookStack\\Page') { $entities[$index] = $this->page->newFromBuilder($rawEntity); - } else if ($rawEntity->entity_type === 'Bookstack\\Chapter') { + } else if ($rawEntity->entity_type === 'BookStack\\Chapter') { $entities[$index] = $this->chapter->newFromBuilder($rawEntity); $key = $entities[$index]->entity_type . ':' . $entities[$index]->id; $parents[$key] = $entities[$index]; @@ -338,7 +338,7 @@ class EntityRepo foreach ($entities as $entity) { if ($entity->chapter_id === 0) continue; - $parentKey = 'Bookstack\\Chapter:' . $entity->chapter_id; + $parentKey = 'BookStack\\Chapter:' . $entity->chapter_id; $chapter = $parents[$parentKey]; $chapter->pages->push($entity); } @@ -796,6 +796,52 @@ class EntityRepo return $html; } + + /** + * Render the page for viewing, Parsing and performing features such as page transclusion. + * @param Page $page + * @return mixed|string + */ + public function renderPage(Page $page) + { + $content = $page->html; + $matches = []; + preg_match_all("/{{@\s?([0-9].*?)}}/", $content, $matches); + if (count($matches[0]) === 0) return $content; + + foreach ($matches[1] as $index => $includeId) { + $splitInclude = explode('#', $includeId, 2); + $pageId = intval($splitInclude[0]); + if (is_nan($pageId)) continue; + + $page = $this->getById('page', $pageId); + if ($page === null) { + $content = str_replace($matches[0][$index], '', $content); + continue; + } + + if (count($splitInclude) === 1) { + $content = str_replace($matches[0][$index], $page->html, $content); + continue; + } + + $doc = new DOMDocument(); + $doc->loadHTML(mb_convert_encoding(''.$page->html.'', 'HTML-ENTITIES', 'UTF-8')); + $matchingElem = $doc->getElementById($splitInclude[1]); + if ($matchingElem === null) { + $content = str_replace($matches[0][$index], '', $content); + continue; + } + $innerContent = ''; + foreach ($matchingElem->childNodes as $childNode) { + $innerContent .= $doc->saveHTML($childNode); + } + $content = str_replace($matches[0][$index], trim($innerContent), $content); + } + + return $content; + } + /** * Get a new draft page instance. * @param Book $book @@ -835,19 +881,19 @@ class EntityRepo /** * Parse the headers on the page to get a navigation menu - * @param Page $page - * @return Collection + * @param String $pageContent + * @return array */ - public function getPageNav(Page $page) + public function getPageNav($pageContent) { - if ($page->html == '') return null; + if ($pageContent == '') return []; libxml_use_internal_errors(true); $doc = new DOMDocument(); - $doc->loadHTML(mb_convert_encoding($page->html, 'HTML-ENTITIES', 'UTF-8')); + $doc->loadHTML(mb_convert_encoding($pageContent, 'HTML-ENTITIES', 'UTF-8')); $xPath = new DOMXPath($doc); $headers = $xPath->query("//h1|//h2|//h3|//h4|//h5|//h6"); - if (is_null($headers)) return null; + if (is_null($headers)) return []; $tree = collect([]); foreach ($headers as $header) { @@ -868,7 +914,7 @@ class EntityRepo return $header; }); } - return $tree; + return $tree->toArray(); } /** diff --git a/app/Repos/PermissionsRepo.php b/app/Repos/PermissionsRepo.php index e1c6d87b1..aa58d1718 100644 --- a/app/Repos/PermissionsRepo.php +++ b/app/Repos/PermissionsRepo.php @@ -93,7 +93,7 @@ class PermissionsRepo $permissions = isset($roleData['permissions']) ? array_keys($roleData['permissions']) : []; $this->assignRolePermissions($role, $permissions); - if ($role->name === 'admin') { + if ($role->system_name === 'admin') { $permissions = $this->permission->all()->pluck('id')->toArray(); $role->permissions()->sync($permissions); } diff --git a/app/Services/ExportService.php b/app/Services/ExportService.php index 50ba75c17..880bc54ad 100644 --- a/app/Services/ExportService.php +++ b/app/Services/ExportService.php @@ -1,10 +1,22 @@ entityRepo = $entityRepo; + } + /** * Convert a page to a self-contained HTML file. * Includes required CSS & image content. Images are base64 encoded into the HTML. @@ -14,7 +26,7 @@ class ExportService public function pageToContainedHtml(Page $page) { $cssContent = file_get_contents(public_path('/css/export-styles.css')); - $pageHtml = view('pages/export', ['page' => $page, 'css' => $cssContent])->render(); + $pageHtml = view('pages/export', ['page' => $page, 'pageContent' => $this->entityRepo->renderPage($page), 'css' => $cssContent])->render(); return $this->containHtml($pageHtml); } @@ -26,7 +38,8 @@ class ExportService public function pageToPdf(Page $page) { $cssContent = file_get_contents(public_path('/css/export-styles.css')); - $pageHtml = view('pages/pdf', ['page' => $page, 'css' => $cssContent])->render(); + $pageHtml = view('pages/pdf', ['page' => $page, 'pageContent' => $this->entityRepo->renderPage($page), 'css' => $cssContent])->render(); +// return $pageHtml; $useWKHTML = config('snappy.pdf.binary') !== false; $containedHtml = $this->containHtml($pageHtml); if ($useWKHTML) { @@ -59,9 +72,13 @@ class ExportService $pathString = $srcString; } if ($isLocal && !file_exists($pathString)) continue; - $imageContent = file_get_contents($pathString); - $imageEncoded = 'data:image/' . pathinfo($pathString, PATHINFO_EXTENSION) . ';base64,' . base64_encode($imageContent); - $newImageString = str_replace($srcString, $imageEncoded, $oldImgString); + try { + $imageContent = file_get_contents($pathString); + $imageEncoded = 'data:image/' . pathinfo($pathString, PATHINFO_EXTENSION) . ';base64,' . base64_encode($imageContent); + $newImageString = str_replace($srcString, $imageEncoded, $oldImgString); + } catch (\ErrorException $e) { + $newImageString = ''; + } $htmlContent = str_replace($oldImgString, $newImageString, $htmlContent); } } @@ -88,14 +105,14 @@ class ExportService /** * Converts the page contents into simple plain text. - * This method filters any bad looking content to - * provide a nice final output. + * This method filters any bad looking content to provide a nice final output. * @param Page $page * @return mixed */ public function pageToPlainText(Page $page) { - $text = $page->text; + $html = $this->entityRepo->renderPage($page); + $text = strip_tags($html); // Replace multiple spaces with single spaces $text = preg_replace('/\ {2,}/', ' ', $text); // Reduce multiple horrid whitespace characters. diff --git a/app/Services/Ldap.php b/app/Services/Ldap.php index 196e46a2f..9c3bec327 100644 --- a/app/Services/Ldap.php +++ b/app/Services/Ldap.php @@ -94,4 +94,4 @@ class Ldap return ldap_bind($ldapConnection, $bindRdn, $bindPassword); } -} \ No newline at end of file +} diff --git a/app/Services/LdapService.php b/app/Services/LdapService.php index 40b24f141..f8a4b88bb 100644 --- a/app/Services/LdapService.php +++ b/app/Services/LdapService.php @@ -112,9 +112,13 @@ class LdapService throw new LdapException(trans('errors.ldap_extension_not_installed')); } - // Get port from server string if specified. + // Get port from server string and protocol if specified. $ldapServer = explode(':', $this->config['server']); - $ldapConnection = $this->ldap->connect($ldapServer[0], count($ldapServer) > 1 ? $ldapServer[1] : 389); + $hasProtocol = preg_match('/^ldaps{0,1}\:\/\//', $this->config['server']) === 1; + if (!$hasProtocol) array_unshift($ldapServer, ''); + $hostName = $ldapServer[0] . ($hasProtocol?':':'') . $ldapServer[1]; + $defaultPort = $ldapServer[0] === 'ldaps' ? 636 : 389; + $ldapConnection = $this->ldap->connect($hostName, count($ldapServer) > 2 ? intval($ldapServer[2]) : $defaultPort); if ($ldapConnection === false) { throw new LdapException(trans('errors.ldap_cannot_connect')); diff --git a/app/Services/PermissionService.php b/app/Services/PermissionService.php index 467bf95da..72a810b6b 100644 --- a/app/Services/PermissionService.php +++ b/app/Services/PermissionService.php @@ -157,7 +157,7 @@ class PermissionService */ public function buildJointPermissionsForEntity(Entity $entity) { - $roles = $this->role->with('jointPermissions')->get(); + $roles = $this->role->get(); $entities = collect([$entity]); if ($entity->isA('book')) { @@ -177,7 +177,7 @@ class PermissionService */ public function buildJointPermissionsForEntities(Collection $entities) { - $roles = $this->role->with('jointPermissions')->get(); + $roles = $this->role->get(); $this->deleteManyJointPermissionsForEntities($entities); $this->createManyJointPermissions($entities, $roles); } @@ -243,13 +243,14 @@ class PermissionService */ protected function deleteManyJointPermissionsForEntities($entities) { + if (count($entities) === 0) return; $query = $this->jointPermission->newQuery(); - foreach ($entities as $entity) { - $query->orWhere(function($query) use ($entity) { - $query->where('entity_id', '=', $entity->id) - ->where('entity_type', '=', $entity->getMorphClass()); - }); - } + foreach ($entities as $entity) { + $query->orWhere(function($query) use ($entity) { + $query->where('entity_id', '=', $entity->id) + ->where('entity_type', '=', $entity->getMorphClass()); + }); + } $query->delete(); } @@ -405,7 +406,7 @@ class PermissionService $action = end($explodedPermission); $this->currentAction = $action; - $nonJointPermissions = ['restrictions']; + $nonJointPermissions = ['restrictions', 'image', 'attachment']; // Handle non entity specific jointPermissions if (in_array($explodedPermission[0], $nonJointPermissions)) { @@ -421,7 +422,6 @@ class PermissionService $this->currentAction = $permission; } - $q = $this->entityRestrictionQuery($baseQuery)->count() > 0; $this->clean(); return $q; @@ -471,49 +471,40 @@ class PermissionService return $q; } + /** + * Get the children of a book in an efficient single query, Filtered by the permission system. + * @param integer $book_id + * @param bool $filterDrafts + * @return \Illuminate\Database\Query\Builder + */ public function bookChildrenQuery($book_id, $filterDrafts = false) { + $pageSelect = $this->db->table('pages')->selectRaw("'BookStack\\\\Page' as entity_type, id, slug, name, text, '' as description, book_id, priority, chapter_id, draft")->where('book_id', '=', $book_id)->where(function($query) use ($filterDrafts) { + $query->where('draft', '=', 0); + if (!$filterDrafts) { + $query->orWhere(function($query) { + $query->where('draft', '=', 1)->where('created_by', '=', $this->currentUser()->id); + }); + } + }); + $chapterSelect = $this->db->table('chapters')->selectRaw("'BookStack\\\\Chapter' as entity_type, id, slug, name, '' as text, description, book_id, priority, 0 as chapter_id, 0 as draft")->where('book_id', '=', $book_id); + $query = $this->db->query()->select('*')->from($this->db->raw("({$pageSelect->toSql()} UNION {$chapterSelect->toSql()}) AS U")) + ->mergeBindings($pageSelect)->mergeBindings($chapterSelect); - // Draft setup - $params = [ - 'userId' => $this->currentUser()->id, - 'bookIdPage' => $book_id, - 'bookIdChapter' => $book_id - ]; - if (!$filterDrafts) { - $params['userIdDrafts'] = $this->currentUser()->id; + if (!$this->isAdmin()) { + $whereQuery = $this->db->table('joint_permissions as jp')->selectRaw('COUNT(*)') + ->whereRaw('jp.entity_id=U.id')->whereRaw('jp.entity_type=U.entity_type') + ->where('jp.action', '=', 'view')->whereIn('jp.role_id', $this->getRoles()) + ->where(function($query) { + $query->where('jp.has_permission', '=', 1)->orWhere(function($query) { + $query->where('jp.has_permission_own', '=', 1)->where('jp.created_by', '=', $this->currentUser()->id); + }); + }); + $query->whereRaw("({$whereQuery->toSql()}) > 0")->mergeBindings($whereQuery); } - // Role setup - $userRoles = $this->getRoles(); - $roleBindings = []; - $roleValues = []; - foreach ($userRoles as $index => $roleId) { - $roleBindings[':role'.$index] = $roleId; - $roleValues['role'.$index] = $roleId; - } - // TODO - Clean this up, Maybe extract into a nice class for doing these kind of manual things - // Something which will handle the above role crap in a nice clean way - $roleBindingString = implode(',', array_keys($roleBindings)); - $query = "SELECT * from ( -(SELECT 'Bookstack\\\Page' as entity_type, id, slug, name, text, '' as description, book_id, priority, chapter_id, draft FROM {$this->page->getTable()} - where book_id = :bookIdPage AND ". ($filterDrafts ? '(draft = 0)' : '(draft = 0 OR (draft = 1 AND created_by = :userIdDrafts))') .") -UNION -(SELECT 'Bookstack\\\Chapter' as entity_type, id, slug, name, '' as text, description, book_id, priority, 0 as chapter_id, 0 as draft FROM {$this->chapter->getTable()} WHERE book_id = :bookIdChapter) -) as U WHERE ( - SELECT COUNT(*) FROM {$this->jointPermission->getTable()} jp - WHERE - jp.entity_id=U.id AND - jp.entity_type=U.entity_type AND - jp.action = 'view' AND - jp.role_id IN ({$roleBindingString}) AND - ( - jp.has_permission = 1 OR - (jp.has_permission_own = 1 AND jp.created_by = :userId) - ) -) > 0 -ORDER BY draft desc, priority asc"; + $query->orderBy('draft', 'desc')->orderBy('priority', 'asc'); $this->clean(); - return $this->db->select($query, array_replace($roleValues, $params)); + return $query; } /** @@ -579,6 +570,7 @@ ORDER BY draft desc, priority asc"; }); }); }); + $this->clean(); return $q; } diff --git a/app/Services/SettingService.php b/app/Services/SettingService.php index bf5fa918e..40094a513 100644 --- a/app/Services/SettingService.php +++ b/app/Services/SettingService.php @@ -1,6 +1,7 @@ getValueFromStore($key, $default); return $this->formatValue($value, $default); } + /** + * Get a user-specific setting from the database or cache. + * @param User $user + * @param $key + * @param bool $default + * @return bool|string + */ + public function getUser($user, $key, $default = false) + { + return $this->get($this->userKey($user->id, $key), $default); + } + /** * Gets a setting value from the cache or database. * Looks at the system defaults if not cached or in database. @@ -69,14 +83,6 @@ class SettingService return $value; } - // Check the defaults set in the app config. - $configPrefix = 'setting-defaults.' . $key; - if (config()->has($configPrefix)) { - $value = config($configPrefix); - $this->cache->forever($cacheKey, $value); - return $value; - } - return $default; } @@ -118,6 +124,16 @@ class SettingService return $setting !== null; } + /** + * Check if a user setting is in the database. + * @param $key + * @return bool + */ + public function hasUser($key) + { + return $this->has($this->userKey($key)); + } + /** * Add a setting to the database. * @param $key @@ -135,6 +151,28 @@ class SettingService return true; } + /** + * Put a user-specific setting into the database. + * @param User $user + * @param $key + * @param $value + * @return bool + */ + public function putUser($user, $key, $value) + { + return $this->put($this->userKey($user->id, $key), $value); + } + + /** + * Convert a setting key into a user-specific key. + * @param $key + * @return string + */ + protected function userKey($userId, $key = '') + { + return 'user:' . $userId . ':' . $key; + } + /** * Removes a setting from the database. * @param $key @@ -150,6 +188,16 @@ class SettingService return true; } + /** + * Delete settings for a given user id. + * @param $userId + * @return mixed + */ + public function deleteUserSettings($userId) + { + return $this->setting->where('setting_key', 'like', $this->userKey($userId) . '%')->delete(); + } + /** * Gets a setting model from the database for the given key. * @param $key diff --git a/app/User.php b/app/User.php index b5bb221e8..afcd9af70 100644 --- a/app/User.php +++ b/app/User.php @@ -160,8 +160,16 @@ class User extends Model implements AuthenticatableContract, CanResetPasswordCon */ public function getAvatar($size = 50) { - if ($this->image_id === 0 || $this->image_id === '0' || $this->image_id === null) return baseUrl('/user_avatar.png'); - return baseUrl($this->avatar->getThumb($size, $size, false)); + $default = baseUrl('/user_avatar.png'); + $imageId = $this->image_id; + if ($imageId === 0 || $imageId === '0' || $imageId === null) return $default; + + try { + $avatar = baseUrl($this->avatar->getThumb($size, $size, false)); + } catch (\Exception $err) { + $avatar = $default; + } + return $avatar; } /** diff --git a/app/helpers.php b/app/helpers.php index b5be0fd11..6decb08e9 100644 --- a/app/helpers.php +++ b/app/helpers.php @@ -60,11 +60,12 @@ function userCan($permission, Ownable $ownable = null) * Helper to access system settings. * @param $key * @param bool $default - * @return mixed + * @return bool|string|\BookStack\Services\SettingService */ -function setting($key, $default = false) +function setting($key = null, $default = false) { $settingService = app(\BookStack\Services\SettingService::class); + if (is_null($key)) return $settingService; return $settingService->get($key, $default); } diff --git a/composer.json b/composer.json index 5a8fd67ae..c0543a4ca 100644 --- a/composer.json +++ b/composer.json @@ -6,17 +6,18 @@ "type": "project", "require": { "php": ">=5.6.4", - "laravel/framework": "^5.3.4", + "laravel/framework": "5.4.*", "ext-tidy": "*", "intervention/image": "^2.3", - "laravel/socialite": "^2.0", - "barryvdh/laravel-ide-helper": "^2.1", - "barryvdh/laravel-debugbar": "^2.2.3", + "laravel/socialite": "^3.0", + "barryvdh/laravel-ide-helper": "^2.2.3", + "barryvdh/laravel-debugbar": "^2.3.2", "league/flysystem-aws-s3-v3": "^1.0", "barryvdh/laravel-dompdf": "^0.7", "predis/predis": "^1.1", "gathercontent/htmldiff": "^0.2.1", - "barryvdh/laravel-snappy": "^0.3.1" + "barryvdh/laravel-snappy": "^0.3.1", + "laravel/browser-kit-testing": "^1.0" }, "require-dev": { "fzaninotto/faker": "~1.4", @@ -35,7 +36,8 @@ }, "autoload-dev": { "classmap": [ - "tests/TestCase.php" + "tests/TestCase.php", + "tests/BrowserKitTest.php" ] }, "scripts": { diff --git a/composer.lock b/composer.lock index dcde9d9c6..e06993611 100644 --- a/composer.lock +++ b/composer.lock @@ -4,21 +4,21 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "hash": "2438a2f4a02adbea5f378f9e9408eb29", - "content-hash": "6add8bff71ecc86e0c90858590834a26", + "hash": "c0bb098e9430247688c61ebd66d3d51c", + "content-hash": "3bb8bb2f252327c32aa40c686d1327cc", "packages": [ { "name": "aws/aws-sdk-php", - "version": "3.19.11", + "version": "3.21.4", "source": { "type": "git", "url": "https://github.com/aws/aws-sdk-php.git", - "reference": "19bac3bdd7988cbf7f89d5ce8e2748d774e2cde8" + "reference": "6408a4904a04eca44461a65ba4a0fae53f80417b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/19bac3bdd7988cbf7f89d5ce8e2748d774e2cde8", - "reference": "19bac3bdd7988cbf7f89d5ce8e2748d774e2cde8", + "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/6408a4904a04eca44461a65ba4a0fae53f80417b", + "reference": "6408a4904a04eca44461a65ba4a0fae53f80417b", "shasum": "" }, "require": { @@ -85,24 +85,24 @@ "s3", "sdk" ], - "time": "2016-09-27 19:38:36" + "time": "2017-01-25 00:43:08" }, { "name": "barryvdh/laravel-debugbar", - "version": "v2.3.0", + "version": "v2.3.2", "source": { "type": "git", "url": "https://github.com/barryvdh/laravel-debugbar.git", - "reference": "0c87981df959c7c1943abe227baf607c92f204f9" + "reference": "24e4f0261e352d3fd86d0447791b56ae49398674" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/barryvdh/laravel-debugbar/zipball/0c87981df959c7c1943abe227baf607c92f204f9", - "reference": "0c87981df959c7c1943abe227baf607c92f204f9", + "url": "https://api.github.com/repos/barryvdh/laravel-debugbar/zipball/24e4f0261e352d3fd86d0447791b56ae49398674", + "reference": "24e4f0261e352d3fd86d0447791b56ae49398674", "shasum": "" }, "require": { - "illuminate/support": "5.1.*|5.2.*|5.3.*", + "illuminate/support": "5.1.*|5.2.*|5.3.*|5.4.*", "maximebf/debugbar": "~1.13.0", "php": ">=5.5.9", "symfony/finder": "~2.7|~3.0" @@ -139,25 +139,25 @@ "profiler", "webprofiler" ], - "time": "2016-09-15 14:05:56" + "time": "2017-01-19 08:19:49" }, { "name": "barryvdh/laravel-dompdf", - "version": "v0.7.0", + "version": "v0.7.1", "source": { "type": "git", "url": "https://github.com/barryvdh/laravel-dompdf.git", - "reference": "9b8bd179262ad6b200a11edfe7b53516afcfc42a" + "reference": "6cb20d3f397d739163d2d743a4600009e52cd453" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/barryvdh/laravel-dompdf/zipball/9b8bd179262ad6b200a11edfe7b53516afcfc42a", - "reference": "9b8bd179262ad6b200a11edfe7b53516afcfc42a", + "url": "https://api.github.com/repos/barryvdh/laravel-dompdf/zipball/6cb20d3f397d739163d2d743a4600009e52cd453", + "reference": "6cb20d3f397d739163d2d743a4600009e52cd453", "shasum": "" }, "require": { "dompdf/dompdf": "^0.7", - "illuminate/support": "5.1.x|5.2.x|5.3.x", + "illuminate/support": "5.1.x|5.2.x|5.3.x|5.4.x", "php": ">=5.5.9" }, "type": "library", @@ -187,27 +187,27 @@ "laravel", "pdf" ], - "time": "2016-08-17 08:17:33" + "time": "2017-01-24 18:12:54" }, { "name": "barryvdh/laravel-ide-helper", - "version": "v2.2.1", + "version": "v2.2.3", "source": { "type": "git", "url": "https://github.com/barryvdh/laravel-ide-helper.git", - "reference": "28af7cd19ca41cc0c63dd1de2b46c2b84d31c463" + "reference": "a7fc2ec489aada6062d3a63ddc915004a21e38af" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/barryvdh/laravel-ide-helper/zipball/28af7cd19ca41cc0c63dd1de2b46c2b84d31c463", - "reference": "28af7cd19ca41cc0c63dd1de2b46c2b84d31c463", + "url": "https://api.github.com/repos/barryvdh/laravel-ide-helper/zipball/a7fc2ec489aada6062d3a63ddc915004a21e38af", + "reference": "a7fc2ec489aada6062d3a63ddc915004a21e38af", "shasum": "" }, "require": { "barryvdh/reflection-docblock": "^2.0.4", - "illuminate/console": "^5.0,<5.4", - "illuminate/filesystem": "^5.0,<5.4", - "illuminate/support": "^5.0,<5.4", + "illuminate/console": "^5.0,<5.5", + "illuminate/filesystem": "^5.0,<5.5", + "illuminate/support": "^5.0,<5.5", "php": ">=5.4.0", "symfony/class-loader": "^2.3|^3.0" }, @@ -253,25 +253,25 @@ "phpstorm", "sublime" ], - "time": "2016-07-04 11:52:48" + "time": "2017-01-05 21:20:42" }, { "name": "barryvdh/laravel-snappy", - "version": "v0.3.1", + "version": "v0.3.2", "source": { "type": "git", "url": "https://github.com/barryvdh/laravel-snappy.git", - "reference": "509a4497be63d8ee7ff464a3daf00d9edde08e21" + "reference": "864470e81952f8e568c93754d9d0d2c05145f773" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/barryvdh/laravel-snappy/zipball/509a4497be63d8ee7ff464a3daf00d9edde08e21", - "reference": "509a4497be63d8ee7ff464a3daf00d9edde08e21", + "url": "https://api.github.com/repos/barryvdh/laravel-snappy/zipball/864470e81952f8e568c93754d9d0d2c05145f773", + "reference": "864470e81952f8e568c93754d9d0d2c05145f773", "shasum": "" }, "require": { - "illuminate/filesystem": "5.0.x|5.1.x|5.2.x|5.3.x", - "illuminate/support": "5.0.x|5.1.x|5.2.x|5.3.x", + "illuminate/filesystem": "5.0.x|5.1.x|5.2.x|5.3.x|5.4.x", + "illuminate/support": "5.0.x|5.1.x|5.2.x|5.3.x|5.4.x", "knplabs/knp-snappy": "*", "php": ">=5.4.0" }, @@ -305,7 +305,7 @@ "wkhtmltoimage", "wkhtmltopdf" ], - "time": "2016-08-05 13:08:28" + "time": "2017-01-20 06:21:34" }, { "name": "barryvdh/reflection-docblock", @@ -356,60 +356,6 @@ ], "time": "2016-06-13 19:28:20" }, - { - "name": "classpreloader/classpreloader", - "version": "3.0.0", - "source": { - "type": "git", - "url": "https://github.com/ClassPreloader/ClassPreloader.git", - "reference": "9b10b913c2bdf90c3d2e0d726b454fb7f77c552a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/ClassPreloader/ClassPreloader/zipball/9b10b913c2bdf90c3d2e0d726b454fb7f77c552a", - "reference": "9b10b913c2bdf90c3d2e0d726b454fb7f77c552a", - "shasum": "" - }, - "require": { - "nikic/php-parser": "^1.0|^2.0", - "php": ">=5.5.9" - }, - "require-dev": { - "phpunit/phpunit": "^4.8|^5.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.0-dev" - } - }, - "autoload": { - "psr-4": { - "ClassPreloader\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Michael Dowling", - "email": "mtdowling@gmail.com" - }, - { - "name": "Graham Campbell", - "email": "graham@alt-three.com" - } - ], - "description": "Helps class loading performance by generating a single PHP file containing all of the autoloaded files for a specific use case", - "keywords": [ - "autoload", - "class", - "preload" - ], - "time": "2015-11-09 22:51:51" - }, { "name": "cogpowered/finediff", "version": "0.3.1", @@ -461,39 +407,6 @@ ], "time": "2014-05-19 10:25:02" }, - { - "name": "dnoegel/php-xdg-base-dir", - "version": "0.1", - "source": { - "type": "git", - "url": "https://github.com/dnoegel/php-xdg-base-dir.git", - "reference": "265b8593498b997dc2d31e75b89f053b5cc9621a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/dnoegel/php-xdg-base-dir/zipball/265b8593498b997dc2d31e75b89f053b5cc9621a", - "reference": "265b8593498b997dc2d31e75b89f053b5cc9621a", - "shasum": "" - }, - "require": { - "php": ">=5.3.2" - }, - "require-dev": { - "phpunit/phpunit": "@stable" - }, - "type": "project", - "autoload": { - "psr-4": { - "XdgBaseDir\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "implementation of xdg base directory specification for php", - "time": "2014-10-24 07:27:01" - }, { "name": "doctrine/inflector", "version": "v1.1.0", @@ -622,6 +535,48 @@ "homepage": "https://github.com/dompdf/dompdf", "time": "2016-05-11 00:36:29" }, + { + "name": "erusev/parsedown", + "version": "1.6.1", + "source": { + "type": "git", + "url": "https://github.com/erusev/parsedown.git", + "reference": "20ff8bbb57205368b4b42d094642a3e52dac85fb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/erusev/parsedown/zipball/20ff8bbb57205368b4b42d094642a3e52dac85fb", + "reference": "20ff8bbb57205368b4b42d094642a3e52dac85fb", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "autoload": { + "psr-0": { + "Parsedown": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Emanuil Rusev", + "email": "hello@erusev.com", + "homepage": "http://erusev.com" + } + ], + "description": "Parser for Markdown.", + "homepage": "http://parsedown.org", + "keywords": [ + "markdown", + "parser" + ], + "time": "2016-11-02 15:56:58" + }, { "name": "gathercontent/htmldiff", "version": "0.2.1", @@ -673,16 +628,16 @@ }, { "name": "guzzlehttp/guzzle", - "version": "6.2.1", + "version": "6.2.2", "source": { "type": "git", "url": "https://github.com/guzzle/guzzle.git", - "reference": "3f808fba627f2c5b69e2501217bf31af349c1427" + "reference": "ebf29dee597f02f09f4d5bbecc68230ea9b08f60" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/guzzle/zipball/3f808fba627f2c5b69e2501217bf31af349c1427", - "reference": "3f808fba627f2c5b69e2501217bf31af349c1427", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/ebf29dee597f02f09f4d5bbecc68230ea9b08f60", + "reference": "ebf29dee597f02f09f4d5bbecc68230ea9b08f60", "shasum": "" }, "require": { @@ -731,32 +686,32 @@ "rest", "web service" ], - "time": "2016-07-15 17:22:37" + "time": "2016-10-08 15:01:37" }, { "name": "guzzlehttp/promises", - "version": "1.2.0", + "version": "v1.3.1", "source": { "type": "git", "url": "https://github.com/guzzle/promises.git", - "reference": "c10d860e2a9595f8883527fa0021c7da9e65f579" + "reference": "a59da6cf61d80060647ff4d3eb2c03a2bc694646" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/promises/zipball/c10d860e2a9595f8883527fa0021c7da9e65f579", - "reference": "c10d860e2a9595f8883527fa0021c7da9e65f579", + "url": "https://api.github.com/repos/guzzle/promises/zipball/a59da6cf61d80060647ff4d3eb2c03a2bc694646", + "reference": "a59da6cf61d80060647ff4d3eb2c03a2bc694646", "shasum": "" }, "require": { "php": ">=5.5.0" }, "require-dev": { - "phpunit/phpunit": "~4.0" + "phpunit/phpunit": "^4.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0-dev" + "dev-master": "1.4-dev" } }, "autoload": { @@ -782,7 +737,7 @@ "keywords": [ "promise" ], - "time": "2016-05-18 16:56:05" + "time": "2016-12-20 10:07:11" }, { "name": "guzzlehttp/psr7", @@ -844,16 +799,16 @@ }, { "name": "intervention/image", - "version": "2.3.8", + "version": "2.3.9", "source": { "type": "git", "url": "https://github.com/Intervention/image.git", - "reference": "4064a980324f6c3bfa2bd981dfb247afa705ec3c" + "reference": "2bce9a59c43b868300b02a7d31a1e4aa67a200ae" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Intervention/image/zipball/4064a980324f6c3bfa2bd981dfb247afa705ec3c", - "reference": "4064a980324f6c3bfa2bd981dfb247afa705ec3c", + "url": "https://api.github.com/repos/Intervention/image/zipball/2bce9a59c43b868300b02a7d31a1e4aa67a200ae", + "reference": "2bce9a59c43b868300b02a7d31a1e4aa67a200ae", "shasum": "" }, "require": { @@ -902,152 +857,7 @@ "thumbnail", "watermark" ], - "time": "2016-09-01 17:04:03" - }, - { - "name": "jakub-onderka/php-console-color", - "version": "0.1", - "source": { - "type": "git", - "url": "https://github.com/JakubOnderka/PHP-Console-Color.git", - "reference": "e0b393dacf7703fc36a4efc3df1435485197e6c1" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/JakubOnderka/PHP-Console-Color/zipball/e0b393dacf7703fc36a4efc3df1435485197e6c1", - "reference": "e0b393dacf7703fc36a4efc3df1435485197e6c1", - "shasum": "" - }, - "require": { - "php": ">=5.3.2" - }, - "require-dev": { - "jakub-onderka/php-code-style": "1.0", - "jakub-onderka/php-parallel-lint": "0.*", - "jakub-onderka/php-var-dump-check": "0.*", - "phpunit/phpunit": "3.7.*", - "squizlabs/php_codesniffer": "1.*" - }, - "type": "library", - "autoload": { - "psr-0": { - "JakubOnderka\\PhpConsoleColor": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-2-Clause" - ], - "authors": [ - { - "name": "Jakub Onderka", - "email": "jakub.onderka@gmail.com", - "homepage": "http://www.acci.cz" - } - ], - "time": "2014-04-08 15:00:19" - }, - { - "name": "jakub-onderka/php-console-highlighter", - "version": "v0.3.2", - "source": { - "type": "git", - "url": "https://github.com/JakubOnderka/PHP-Console-Highlighter.git", - "reference": "7daa75df45242c8d5b75a22c00a201e7954e4fb5" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/JakubOnderka/PHP-Console-Highlighter/zipball/7daa75df45242c8d5b75a22c00a201e7954e4fb5", - "reference": "7daa75df45242c8d5b75a22c00a201e7954e4fb5", - "shasum": "" - }, - "require": { - "jakub-onderka/php-console-color": "~0.1", - "php": ">=5.3.0" - }, - "require-dev": { - "jakub-onderka/php-code-style": "~1.0", - "jakub-onderka/php-parallel-lint": "~0.5", - "jakub-onderka/php-var-dump-check": "~0.1", - "phpunit/phpunit": "~4.0", - "squizlabs/php_codesniffer": "~1.5" - }, - "type": "library", - "autoload": { - "psr-0": { - "JakubOnderka\\PhpConsoleHighlighter": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Jakub Onderka", - "email": "acci@acci.cz", - "homepage": "http://www.acci.cz/" - } - ], - "time": "2015-04-20 18:58:01" - }, - { - "name": "jeremeamia/SuperClosure", - "version": "2.2.0", - "source": { - "type": "git", - "url": "https://github.com/jeremeamia/super_closure.git", - "reference": "29a88be2a4846d27c1613aed0c9071dfad7b5938" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/jeremeamia/super_closure/zipball/29a88be2a4846d27c1613aed0c9071dfad7b5938", - "reference": "29a88be2a4846d27c1613aed0c9071dfad7b5938", - "shasum": "" - }, - "require": { - "nikic/php-parser": "^1.2|^2.0", - "php": ">=5.4", - "symfony/polyfill-php56": "^1.0" - }, - "require-dev": { - "phpunit/phpunit": "^4.0|^5.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.2-dev" - } - }, - "autoload": { - "psr-4": { - "SuperClosure\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Jeremy Lindblom", - "email": "jeremeamia@gmail.com", - "homepage": "https://github.com/jeremeamia", - "role": "Developer" - } - ], - "description": "Serialize Closure objects, including their context and binding", - "homepage": "https://github.com/jeremeamia/super_closure", - "keywords": [ - "closure", - "function", - "lambda", - "parser", - "serializable", - "serialize", - "tokenizer" - ], - "time": "2015-12-05 17:17:57" + "time": "2017-01-10 14:15:56" }, { "name": "knplabs/knp-snappy", @@ -1115,43 +925,88 @@ "time": "2015-11-17 13:16:27" }, { - "name": "laravel/framework", - "version": "v5.3.11", + "name": "laravel/browser-kit-testing", + "version": "v1.0.2", "source": { "type": "git", - "url": "https://github.com/laravel/framework.git", - "reference": "ca48001b95a0543fb39fcd7219de960bbc03eaa5" + "url": "https://github.com/laravel/browser-kit-testing.git", + "reference": "60e038e3dcfef2977347f9610c14b48721802278" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/framework/zipball/ca48001b95a0543fb39fcd7219de960bbc03eaa5", - "reference": "ca48001b95a0543fb39fcd7219de960bbc03eaa5", + "url": "https://api.github.com/repos/laravel/browser-kit-testing/zipball/60e038e3dcfef2977347f9610c14b48721802278", + "reference": "60e038e3dcfef2977347f9610c14b48721802278", + "shasum": "" + }, + "require": { + "php": ">=5.5.9", + "symfony/css-selector": "3.1.*", + "symfony/dom-crawler": "3.1.*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "psr-4": { + "Laravel\\BrowserKitTesting\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + } + ], + "description": "Provides backwards compatibility for BrowserKit testing in Laravel 5.4.", + "keywords": [ + "laravel", + "testing" + ], + "time": "2017-01-25 13:07:25" + }, + { + "name": "laravel/framework", + "version": "v5.4.3", + "source": { + "type": "git", + "url": "https://github.com/laravel/framework.git", + "reference": "9fa94bf77272ea7f920292c6f016b0f6e0853f98" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laravel/framework/zipball/9fa94bf77272ea7f920292c6f016b0f6e0853f98", + "reference": "9fa94bf77272ea7f920292c6f016b0f6e0853f98", "shasum": "" }, "require": { - "classpreloader/classpreloader": "~3.0", "doctrine/inflector": "~1.0", + "erusev/parsedown": "~1.6", "ext-mbstring": "*", "ext-openssl": "*", - "jeremeamia/superclosure": "~2.2", "league/flysystem": "~1.0", "monolog/monolog": "~1.11", "mtdowling/cron-expression": "~1.0", "nesbot/carbon": "~1.20", "paragonie/random_compat": "~1.4|~2.0", "php": ">=5.6.4", - "psy/psysh": "0.7.*", "ramsey/uuid": "~3.0", - "swiftmailer/swiftmailer": "~5.1", - "symfony/console": "3.1.*", - "symfony/debug": "3.1.*", - "symfony/finder": "3.1.*", - "symfony/http-foundation": "3.1.*", - "symfony/http-kernel": "3.1.*", - "symfony/process": "3.1.*", - "symfony/routing": "3.1.*", - "symfony/translation": "3.1.*", - "symfony/var-dumper": "3.1.*", + "swiftmailer/swiftmailer": "~5.4", + "symfony/console": "~3.2", + "symfony/debug": "~3.2", + "symfony/finder": "~3.2", + "symfony/http-foundation": "~3.2", + "symfony/http-kernel": "~3.2", + "symfony/process": "~3.2", + "symfony/routing": "~3.2", + "symfony/var-dumper": "~3.2", + "tijsverkoyen/css-to-inline-styles": "~2.2", "vlucas/phpdotenv": "~2.2" }, "replace": { @@ -1188,31 +1043,34 @@ }, "require-dev": { "aws/aws-sdk-php": "~3.0", + "doctrine/dbal": "~2.5", "mockery/mockery": "~0.9.4", "pda/pheanstalk": "~3.0", - "phpunit/phpunit": "~5.4", + "phpunit/phpunit": "~5.7", "predis/predis": "~1.0", - "symfony/css-selector": "3.1.*", - "symfony/dom-crawler": "3.1.*" + "symfony/css-selector": "~3.2", + "symfony/dom-crawler": "~3.2" }, "suggest": { "aws/aws-sdk-php": "Required to use the SQS queue driver and SES mail driver (~3.0).", - "doctrine/dbal": "Required to rename columns and drop SQLite columns (~2.4).", + "doctrine/dbal": "Required to rename columns and drop SQLite columns (~2.5).", "fzaninotto/faker": "Required to use the eloquent factory builder (~1.4).", - "guzzlehttp/guzzle": "Required to use the Mailgun and Mandrill mail drivers and the ping methods on schedules (~5.3|~6.0).", + "guzzlehttp/guzzle": "Required to use the Mailgun and Mandrill mail drivers and the ping methods on schedules (~6.0).", + "laravel/tinker": "Required to use the tinker console command (~1.0).", "league/flysystem-aws-s3-v3": "Required to use the Flysystem S3 driver (~1.0).", "league/flysystem-rackspace": "Required to use the Flysystem Rackspace driver (~1.0).", + "nexmo/client": "Required to use the Nexmo transport (~1.0).", "pda/pheanstalk": "Required to use the beanstalk queue driver (~3.0).", "predis/predis": "Required to use the redis cache and queue drivers (~1.0).", "pusher/pusher-php-server": "Required to use the Pusher broadcast driver (~2.0).", - "symfony/css-selector": "Required to use some of the crawler integration testing tools (3.1.*).", - "symfony/dom-crawler": "Required to use most of the crawler integration testing tools (3.1.*).", + "symfony/css-selector": "Required to use some of the crawler integration testing tools (~3.2).", + "symfony/dom-crawler": "Required to use most of the crawler integration testing tools (~3.2).", "symfony/psr-http-message-bridge": "Required to psr7 bridging features (0.2.*)." }, "type": "library", "extra": { "branch-alias": { - "dev-master": "5.3-dev" + "dev-master": "5.4-dev" } }, "autoload": { @@ -1240,27 +1098,27 @@ "framework", "laravel" ], - "time": "2016-09-28 02:15:37" + "time": "2017-01-25 16:40:49" }, { "name": "laravel/socialite", - "version": "v2.0.18", + "version": "v3.0.2", "source": { "type": "git", "url": "https://github.com/laravel/socialite.git", - "reference": "76ee5397fcdea5a062361392abca4eb397e519a3" + "reference": "d3aaffa5e122395e54eb2c26062fde3a848c40fd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/socialite/zipball/76ee5397fcdea5a062361392abca4eb397e519a3", - "reference": "76ee5397fcdea5a062361392abca4eb397e519a3", + "url": "https://api.github.com/repos/laravel/socialite/zipball/d3aaffa5e122395e54eb2c26062fde3a848c40fd", + "reference": "d3aaffa5e122395e54eb2c26062fde3a848c40fd", "shasum": "" }, "require": { - "guzzlehttp/guzzle": "~5.0|~6.0", - "illuminate/contracts": "~5.0", - "illuminate/http": "~5.0", - "illuminate/support": "~5.0", + "guzzlehttp/guzzle": "~6.0", + "illuminate/contracts": "~5.4", + "illuminate/http": "~5.4", + "illuminate/support": "~5.4", "league/oauth1-client": "~1.0", "php": ">=5.4.0" }, @@ -1294,24 +1152,24 @@ "laravel", "oauth" ], - "time": "2016-06-22 12:40:16" + "time": "2017-01-25 17:58:13" }, { "name": "league/flysystem", - "version": "1.0.27", + "version": "1.0.33", "source": { "type": "git", "url": "https://github.com/thephpleague/flysystem.git", - "reference": "50e2045ed70a7e75a5e30bc3662904f3b67af8a9" + "reference": "5c7f98498b12d47f9de90ec9186a90000125777c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/50e2045ed70a7e75a5e30bc3662904f3b67af8a9", - "reference": "50e2045ed70a7e75a5e30bc3662904f3b67af8a9", + "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/5c7f98498b12d47f9de90ec9186a90000125777c", + "reference": "5c7f98498b12d47f9de90ec9186a90000125777c", "shasum": "" }, "require": { - "php": ">=5.4.0" + "php": ">=5.5.9" }, "conflict": { "league/flysystem-sftp": "<1.0.6" @@ -1377,7 +1235,7 @@ "sftp", "storage" ], - "time": "2016-08-10 08:55:11" + "time": "2017-01-23 10:32:09" }, { "name": "league/flysystem-aws-s3-v3", @@ -1491,16 +1349,16 @@ }, { "name": "maximebf/debugbar", - "version": "v1.13.0", + "version": "1.13.1", "source": { "type": "git", "url": "https://github.com/maximebf/php-debugbar.git", - "reference": "5f49a5ed6cfde81d31d89378806670d77462526e" + "reference": "afee79a236348e39a44cb837106b7c5b4897ac2a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/maximebf/php-debugbar/zipball/5f49a5ed6cfde81d31d89378806670d77462526e", - "reference": "5f49a5ed6cfde81d31d89378806670d77462526e", + "url": "https://api.github.com/repos/maximebf/php-debugbar/zipball/afee79a236348e39a44cb837106b7c5b4897ac2a", + "reference": "afee79a236348e39a44cb837106b7c5b4897ac2a", "shasum": "" }, "require": { @@ -1548,20 +1406,20 @@ "debug", "debugbar" ], - "time": "2016-09-15 14:01:59" + "time": "2017-01-05 08:46:19" }, { "name": "monolog/monolog", - "version": "1.21.0", + "version": "1.22.0", "source": { "type": "git", "url": "https://github.com/Seldaek/monolog.git", - "reference": "f42fbdfd53e306bda545845e4dbfd3e72edb4952" + "reference": "bad29cb8d18ab0315e6c477751418a82c850d558" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Seldaek/monolog/zipball/f42fbdfd53e306bda545845e4dbfd3e72edb4952", - "reference": "f42fbdfd53e306bda545845e4dbfd3e72edb4952", + "url": "https://api.github.com/repos/Seldaek/monolog/zipball/bad29cb8d18ab0315e6c477751418a82c850d558", + "reference": "bad29cb8d18ab0315e6c477751418a82c850d558", "shasum": "" }, "require": { @@ -1572,7 +1430,7 @@ "psr/log-implementation": "1.0.0" }, "require-dev": { - "aws/aws-sdk-php": "^2.4.9", + "aws/aws-sdk-php": "^2.4.9 || ^3.0", "doctrine/couchdb": "~1.0@dev", "graylog2/gelf-php": "~1.0", "jakub-onderka/php-parallel-lint": "0.9", @@ -1626,20 +1484,20 @@ "logging", "psr-3" ], - "time": "2016-07-29 03:23:52" + "time": "2016-11-26 00:15:39" }, { "name": "mtdowling/cron-expression", - "version": "v1.1.0", + "version": "v1.2.0", "source": { "type": "git", "url": "https://github.com/mtdowling/cron-expression.git", - "reference": "c9ee7886f5a12902b225a1a12f36bb45f9ab89e5" + "reference": "9504fa9ea681b586028adaaa0877db4aecf32bad" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/mtdowling/cron-expression/zipball/c9ee7886f5a12902b225a1a12f36bb45f9ab89e5", - "reference": "c9ee7886f5a12902b225a1a12f36bb45f9ab89e5", + "url": "https://api.github.com/repos/mtdowling/cron-expression/zipball/9504fa9ea681b586028adaaa0877db4aecf32bad", + "reference": "9504fa9ea681b586028adaaa0877db4aecf32bad", "shasum": "" }, "require": { @@ -1650,8 +1508,8 @@ }, "type": "library", "autoload": { - "psr-0": { - "Cron": "src/" + "psr-4": { + "Cron\\": "src/Cron/" } }, "notification-url": "https://packagist.org/downloads/", @@ -1670,20 +1528,20 @@ "cron", "schedule" ], - "time": "2016-01-26 21:23:30" + "time": "2017-01-23 04:29:33" }, { "name": "mtdowling/jmespath.php", - "version": "2.3.0", + "version": "2.4.0", "source": { "type": "git", "url": "https://github.com/jmespath/jmespath.php.git", - "reference": "192f93e43c2c97acde7694993ab171b3de284093" + "reference": "adcc9531682cf87dfda21e1fd5d0e7a41d292fac" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/jmespath/jmespath.php/zipball/192f93e43c2c97acde7694993ab171b3de284093", - "reference": "192f93e43c2c97acde7694993ab171b3de284093", + "url": "https://api.github.com/repos/jmespath/jmespath.php/zipball/adcc9531682cf87dfda21e1fd5d0e7a41d292fac", + "reference": "adcc9531682cf87dfda21e1fd5d0e7a41d292fac", "shasum": "" }, "require": { @@ -1725,30 +1583,36 @@ "json", "jsonpath" ], - "time": "2016-01-05 18:25:05" + "time": "2016-12-03 22:08:25" }, { "name": "nesbot/carbon", - "version": "1.21.0", + "version": "1.22.1", "source": { "type": "git", "url": "https://github.com/briannesbitt/Carbon.git", - "reference": "7b08ec6f75791e130012f206e3f7b0e76e18e3d7" + "reference": "7cdf42c0b1cc763ab7e4c33c47a24e27c66bfccc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/7b08ec6f75791e130012f206e3f7b0e76e18e3d7", - "reference": "7b08ec6f75791e130012f206e3f7b0e76e18e3d7", + "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/7cdf42c0b1cc763ab7e4c33c47a24e27c66bfccc", + "reference": "7cdf42c0b1cc763ab7e4c33c47a24e27c66bfccc", "shasum": "" }, "require": { "php": ">=5.3.0", - "symfony/translation": "~2.6|~3.0" + "symfony/translation": "~2.6 || ~3.0" }, "require-dev": { - "phpunit/phpunit": "~4.0|~5.0" + "friendsofphp/php-cs-fixer": "~2", + "phpunit/phpunit": "~4.0 || ~5.0" }, "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.23-dev" + } + }, "autoload": { "psr-4": { "Carbon\\": "src/Carbon/" @@ -1772,71 +1636,20 @@ "datetime", "time" ], - "time": "2015-11-04 20:07:17" - }, - { - "name": "nikic/php-parser", - "version": "v2.1.1", - "source": { - "type": "git", - "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "4dd659edadffdc2143e4753df655d866dbfeedf0" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/4dd659edadffdc2143e4753df655d866dbfeedf0", - "reference": "4dd659edadffdc2143e4753df655d866dbfeedf0", - "shasum": "" - }, - "require": { - "ext-tokenizer": "*", - "php": ">=5.4" - }, - "require-dev": { - "phpunit/phpunit": "~4.0" - }, - "bin": [ - "bin/php-parse" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.1-dev" - } - }, - "autoload": { - "psr-4": { - "PhpParser\\": "lib/PhpParser" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Nikita Popov" - } - ], - "description": "A PHP parser written in PHP", - "keywords": [ - "parser", - "php" - ], - "time": "2016-09-16 12:04:44" + "time": "2017-01-16 07:55:07" }, { "name": "paragonie/random_compat", - "version": "v2.0.2", + "version": "v2.0.4", "source": { "type": "git", "url": "https://github.com/paragonie/random_compat.git", - "reference": "088c04e2f261c33bed6ca5245491cfca69195ccf" + "reference": "a9b97968bcde1c4de2a5ec6cbd06a0f6c919b46e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/paragonie/random_compat/zipball/088c04e2f261c33bed6ca5245491cfca69195ccf", - "reference": "088c04e2f261c33bed6ca5245491cfca69195ccf", + "url": "https://api.github.com/repos/paragonie/random_compat/zipball/a9b97968bcde1c4de2a5ec6cbd06a0f6c919b46e", + "reference": "a9b97968bcde1c4de2a5ec6cbd06a0f6c919b46e", "shasum": "" }, "require": { @@ -1871,7 +1684,7 @@ "pseudorandom", "random" ], - "time": "2016-04-03 06:00:07" + "time": "2016-11-07 23:38:38" }, { "name": "phenx/php-font-lib", @@ -2043,16 +1856,16 @@ }, { "name": "psr/log", - "version": "1.0.1", + "version": "1.0.2", "source": { "type": "git", "url": "https://github.com/php-fig/log.git", - "reference": "5277094ed527a1c4477177d102fe4c53551953e0" + "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/log/zipball/5277094ed527a1c4477177d102fe4c53551953e0", - "reference": "5277094ed527a1c4477177d102fe4c53551953e0", + "url": "https://api.github.com/repos/php-fig/log/zipball/4ebe3a8bf773a19edfe0a84b6585ba3d401b724d", + "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d", "shasum": "" }, "require": { @@ -2086,92 +1899,20 @@ "psr", "psr-3" ], - "time": "2016-09-19 16:02:08" - }, - { - "name": "psy/psysh", - "version": "v0.7.2", - "source": { - "type": "git", - "url": "https://github.com/bobthecow/psysh.git", - "reference": "e64e10b20f8d229cac76399e1f3edddb57a0f280" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/bobthecow/psysh/zipball/e64e10b20f8d229cac76399e1f3edddb57a0f280", - "reference": "e64e10b20f8d229cac76399e1f3edddb57a0f280", - "shasum": "" - }, - "require": { - "dnoegel/php-xdg-base-dir": "0.1", - "jakub-onderka/php-console-highlighter": "0.3.*", - "nikic/php-parser": "^1.2.1|~2.0", - "php": ">=5.3.9", - "symfony/console": "~2.3.10|^2.4.2|~3.0", - "symfony/var-dumper": "~2.7|~3.0" - }, - "require-dev": { - "fabpot/php-cs-fixer": "~1.5", - "phpunit/phpunit": "~3.7|~4.0|~5.0", - "squizlabs/php_codesniffer": "~2.0", - "symfony/finder": "~2.1|~3.0" - }, - "suggest": { - "ext-pcntl": "Enabling the PCNTL extension makes PsySH a lot happier :)", - "ext-pdo-sqlite": "The doc command requires SQLite to work.", - "ext-posix": "If you have PCNTL, you'll want the POSIX extension as well.", - "ext-readline": "Enables support for arrow-key history navigation, and showing and manipulating command history." - }, - "bin": [ - "bin/psysh" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-develop": "0.8.x-dev" - } - }, - "autoload": { - "files": [ - "src/Psy/functions.php" - ], - "psr-4": { - "Psy\\": "src/Psy/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Justin Hileman", - "email": "justin@justinhileman.info", - "homepage": "http://justinhileman.com" - } - ], - "description": "An interactive shell for modern PHP.", - "homepage": "http://psysh.org", - "keywords": [ - "REPL", - "console", - "interactive", - "shell" - ], - "time": "2016-03-09 05:03:14" + "time": "2016-10-10 12:19:37" }, { "name": "ramsey/uuid", - "version": "3.5.0", + "version": "3.5.2", "source": { "type": "git", "url": "https://github.com/ramsey/uuid.git", - "reference": "a6d15c8618ea3951fd54d34e326b68d3d0bc0786" + "reference": "5677cfe02397dd6b58c861870dfaa5d9007d3954" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/ramsey/uuid/zipball/a6d15c8618ea3951fd54d34e326b68d3d0bc0786", - "reference": "a6d15c8618ea3951fd54d34e326b68d3d0bc0786", + "url": "https://api.github.com/repos/ramsey/uuid/zipball/5677cfe02397dd6b58c861870dfaa5d9007d3954", + "reference": "5677cfe02397dd6b58c861870dfaa5d9007d3954", "shasum": "" }, "require": { @@ -2184,11 +1925,13 @@ "require-dev": { "apigen/apigen": "^4.1", "codeception/aspect-mock": "1.0.0", + "doctrine/annotations": "~1.2.0", "goaop/framework": "1.0.0-alpha.2", "ircmaxell/random-lib": "^1.1", "jakub-onderka/php-parallel-lint": "^0.9.0", "mockery/mockery": "^0.9.4", "moontoast/math": "^1.1", + "php-mock/php-mock-phpunit": "^0.3|^1.1", "phpunit/phpunit": "^4.7|>=5.0 <5.4", "satooshi/php-coveralls": "^0.6.1", "squizlabs/php_codesniffer": "^2.3" @@ -2238,27 +1981,28 @@ "identifier", "uuid" ], - "time": "2016-08-02 18:39:32" + "time": "2016-11-22 19:21:44" }, { "name": "swiftmailer/swiftmailer", - "version": "v5.4.3", + "version": "v5.4.5", "source": { "type": "git", "url": "https://github.com/swiftmailer/swiftmailer.git", - "reference": "4cc92842069c2bbc1f28daaaf1d2576ec4dfe153" + "reference": "cd142238a339459b10da3d8234220963f392540c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/swiftmailer/swiftmailer/zipball/4cc92842069c2bbc1f28daaaf1d2576ec4dfe153", - "reference": "4cc92842069c2bbc1f28daaaf1d2576ec4dfe153", + "url": "https://api.github.com/repos/swiftmailer/swiftmailer/zipball/cd142238a339459b10da3d8234220963f392540c", + "reference": "cd142238a339459b10da3d8234220963f392540c", "shasum": "" }, "require": { "php": ">=5.3.3" }, "require-dev": { - "mockery/mockery": "~0.9.1" + "mockery/mockery": "~0.9.1", + "symfony/phpunit-bridge": "~3.2" }, "type": "library", "extra": { @@ -2291,20 +2035,20 @@ "mail", "mailer" ], - "time": "2016-07-08 11:51:25" + "time": "2016-12-29 10:02:40" }, { "name": "symfony/class-loader", - "version": "v3.1.4", + "version": "v3.2.2", "source": { "type": "git", "url": "https://github.com/symfony/class-loader.git", - "reference": "2d0ba77c46ecc96a6641009a98f72632216811ba" + "reference": "0152f7a47acd564ca62c652975c2b32ac6d613a6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/class-loader/zipball/2d0ba77c46ecc96a6641009a98f72632216811ba", - "reference": "2d0ba77c46ecc96a6641009a98f72632216811ba", + "url": "https://api.github.com/repos/symfony/class-loader/zipball/0152f7a47acd564ca62c652975c2b32ac6d613a6", + "reference": "0152f7a47acd564ca62c652975c2b32ac6d613a6", "shasum": "" }, "require": { @@ -2320,7 +2064,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "3.1-dev" + "dev-master": "3.2-dev" } }, "autoload": { @@ -2347,40 +2091,43 @@ ], "description": "Symfony ClassLoader Component", "homepage": "https://symfony.com", - "time": "2016-08-23 13:39:15" + "time": "2017-01-10 14:14:38" }, { "name": "symfony/console", - "version": "v3.1.4", + "version": "v3.2.2", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "8ea494c34f0f772c3954b5fbe00bffc5a435e563" + "reference": "4f9e449e76996adf310498a8ca955c6deebe29dd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/8ea494c34f0f772c3954b5fbe00bffc5a435e563", - "reference": "8ea494c34f0f772c3954b5fbe00bffc5a435e563", + "url": "https://api.github.com/repos/symfony/console/zipball/4f9e449e76996adf310498a8ca955c6deebe29dd", + "reference": "4f9e449e76996adf310498a8ca955c6deebe29dd", "shasum": "" }, "require": { "php": ">=5.5.9", + "symfony/debug": "~2.8|~3.0", "symfony/polyfill-mbstring": "~1.0" }, "require-dev": { "psr/log": "~1.0", "symfony/event-dispatcher": "~2.8|~3.0", + "symfony/filesystem": "~2.8|~3.0", "symfony/process": "~2.8|~3.0" }, "suggest": { "psr/log": "For using the console logger", "symfony/event-dispatcher": "", + "symfony/filesystem": "", "symfony/process": "" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "3.1-dev" + "dev-master": "3.2-dev" } }, "autoload": { @@ -2407,20 +2154,73 @@ ], "description": "Symfony Console Component", "homepage": "https://symfony.com", - "time": "2016-08-19 06:48:39" + "time": "2017-01-08 20:47:33" }, { - "name": "symfony/debug", - "version": "v3.1.4", + "name": "symfony/css-selector", + "version": "v3.1.9", "source": { "type": "git", - "url": "https://github.com/symfony/debug.git", - "reference": "34f6ac18c2974ca5fce68adf419ee7d15def6f11" + "url": "https://github.com/symfony/css-selector.git", + "reference": "722a87478a72d95dc2a3bcf41dc9c2d13fd4cb2d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/debug/zipball/34f6ac18c2974ca5fce68adf419ee7d15def6f11", - "reference": "34f6ac18c2974ca5fce68adf419ee7d15def6f11", + "url": "https://api.github.com/repos/symfony/css-selector/zipball/722a87478a72d95dc2a3bcf41dc9c2d13fd4cb2d", + "reference": "722a87478a72d95dc2a3bcf41dc9c2d13fd4cb2d", + "shasum": "" + }, + "require": { + "php": ">=5.5.9" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\CssSelector\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jean-François Simon", + "email": "jeanfrancois.simon@sensiolabs.com" + }, + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony CssSelector Component", + "homepage": "https://symfony.com", + "time": "2017-01-02 20:31:54" + }, + { + "name": "symfony/debug", + "version": "v3.2.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/debug.git", + "reference": "810ba5c1c5352a4ddb15d4719e8936751dff0b05" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/debug/zipball/810ba5c1c5352a4ddb15d4719e8936751dff0b05", + "reference": "810ba5c1c5352a4ddb15d4719e8936751dff0b05", "shasum": "" }, "require": { @@ -2437,7 +2237,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "3.1-dev" + "dev-master": "3.2-dev" } }, "autoload": { @@ -2464,20 +2264,76 @@ ], "description": "Symfony Debug Component", "homepage": "https://symfony.com", - "time": "2016-08-23 13:39:15" + "time": "2017-01-02 20:32:22" }, { - "name": "symfony/event-dispatcher", - "version": "v3.1.4", + "name": "symfony/dom-crawler", + "version": "v3.1.9", "source": { "type": "git", - "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "c0c00c80b3a69132c4e55c3e7db32b4a387615e5" + "url": "https://github.com/symfony/dom-crawler.git", + "reference": "a950260ebc947578fba82a3222e2085d90682376" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/c0c00c80b3a69132c4e55c3e7db32b4a387615e5", - "reference": "c0c00c80b3a69132c4e55c3e7db32b4a387615e5", + "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/a950260ebc947578fba82a3222e2085d90682376", + "reference": "a950260ebc947578fba82a3222e2085d90682376", + "shasum": "" + }, + "require": { + "php": ">=5.5.9", + "symfony/polyfill-mbstring": "~1.0" + }, + "require-dev": { + "symfony/css-selector": "~2.8|~3.0" + }, + "suggest": { + "symfony/css-selector": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\DomCrawler\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony DomCrawler Component", + "homepage": "https://symfony.com", + "time": "2017-01-02 20:31:54" + }, + { + "name": "symfony/event-dispatcher", + "version": "v3.2.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/event-dispatcher.git", + "reference": "9137eb3a3328e413212826d63eeeb0217836e2b6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/9137eb3a3328e413212826d63eeeb0217836e2b6", + "reference": "9137eb3a3328e413212826d63eeeb0217836e2b6", "shasum": "" }, "require": { @@ -2497,7 +2353,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "3.1-dev" + "dev-master": "3.2-dev" } }, "autoload": { @@ -2524,20 +2380,20 @@ ], "description": "Symfony EventDispatcher Component", "homepage": "https://symfony.com", - "time": "2016-07-19 10:45:57" + "time": "2017-01-02 20:32:22" }, { "name": "symfony/finder", - "version": "v3.1.4", + "version": "v3.2.2", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "e568ef1784f447a0e54dcb6f6de30b9747b0f577" + "reference": "8c71141cae8e2957946b403cc71a67213c0380d6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/e568ef1784f447a0e54dcb6f6de30b9747b0f577", - "reference": "e568ef1784f447a0e54dcb6f6de30b9747b0f577", + "url": "https://api.github.com/repos/symfony/finder/zipball/8c71141cae8e2957946b403cc71a67213c0380d6", + "reference": "8c71141cae8e2957946b403cc71a67213c0380d6", "shasum": "" }, "require": { @@ -2546,7 +2402,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "3.1-dev" + "dev-master": "3.2-dev" } }, "autoload": { @@ -2573,20 +2429,20 @@ ], "description": "Symfony Finder Component", "homepage": "https://symfony.com", - "time": "2016-08-26 12:04:02" + "time": "2017-01-02 20:32:22" }, { "name": "symfony/http-foundation", - "version": "v3.1.4", + "version": "v3.2.2", "source": { "type": "git", "url": "https://github.com/symfony/http-foundation.git", - "reference": "63592e00fd90632b57ee50220a1ddb29b6bf3bb4" + "reference": "33eb76bf1d833c705433e5361a646c164696394b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-foundation/zipball/63592e00fd90632b57ee50220a1ddb29b6bf3bb4", - "reference": "63592e00fd90632b57ee50220a1ddb29b6bf3bb4", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/33eb76bf1d833c705433e5361a646c164696394b", + "reference": "33eb76bf1d833c705433e5361a646c164696394b", "shasum": "" }, "require": { @@ -2599,7 +2455,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "3.1-dev" + "dev-master": "3.2-dev" } }, "autoload": { @@ -2626,20 +2482,20 @@ ], "description": "Symfony HttpFoundation Component", "homepage": "https://symfony.com", - "time": "2016-08-22 12:11:19" + "time": "2017-01-08 20:47:33" }, { "name": "symfony/http-kernel", - "version": "v3.1.4", + "version": "v3.2.2", "source": { "type": "git", "url": "https://github.com/symfony/http-kernel.git", - "reference": "aeda215d6b01f119508c090d2a09ebb5b0bc61f3" + "reference": "8a898e340a89022246645b1288d295f49c9381e4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-kernel/zipball/aeda215d6b01f119508c090d2a09ebb5b0bc61f3", - "reference": "aeda215d6b01f119508c090d2a09ebb5b0bc61f3", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/8a898e340a89022246645b1288d295f49c9381e4", + "reference": "8a898e340a89022246645b1288d295f49c9381e4", "shasum": "" }, "require": { @@ -2647,7 +2503,7 @@ "psr/log": "~1.0", "symfony/debug": "~2.8|~3.0", "symfony/event-dispatcher": "~2.8|~3.0", - "symfony/http-foundation": "~2.8.8|~3.0.8|~3.1.2|~3.2" + "symfony/http-foundation": "~2.8.13|~3.1.6|~3.2" }, "conflict": { "symfony/config": "<2.8" @@ -2667,7 +2523,7 @@ "symfony/stopwatch": "~2.8|~3.0", "symfony/templating": "~2.8|~3.0", "symfony/translation": "~2.8|~3.0", - "symfony/var-dumper": "~2.8|~3.0" + "symfony/var-dumper": "~3.2" }, "suggest": { "symfony/browser-kit": "", @@ -2681,7 +2537,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "3.1-dev" + "dev-master": "3.2-dev" } }, "autoload": { @@ -2708,20 +2564,20 @@ ], "description": "Symfony HttpKernel Component", "homepage": "https://symfony.com", - "time": "2016-09-03 15:28:24" + "time": "2017-01-12 21:36:33" }, { "name": "symfony/polyfill-mbstring", - "version": "v1.2.0", + "version": "v1.3.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "dff51f72b0706335131b00a7f49606168c582594" + "reference": "e79d363049d1c2128f133a2667e4f4190904f7f4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/dff51f72b0706335131b00a7f49606168c582594", - "reference": "dff51f72b0706335131b00a7f49606168c582594", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/e79d363049d1c2128f133a2667e4f4190904f7f4", + "reference": "e79d363049d1c2128f133a2667e4f4190904f7f4", "shasum": "" }, "require": { @@ -2733,7 +2589,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.2-dev" + "dev-master": "1.3-dev" } }, "autoload": { @@ -2767,128 +2623,20 @@ "portable", "shim" ], - "time": "2016-05-18 14:26:46" - }, - { - "name": "symfony/polyfill-php56", - "version": "v1.2.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-php56.git", - "reference": "3edf57a8fbf9a927533344cef65ad7e1cf31030a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php56/zipball/3edf57a8fbf9a927533344cef65ad7e1cf31030a", - "reference": "3edf57a8fbf9a927533344cef65ad7e1cf31030a", - "shasum": "" - }, - "require": { - "php": ">=5.3.3", - "symfony/polyfill-util": "~1.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.2-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Php56\\": "" - }, - "files": [ - "bootstrap.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill backporting some PHP 5.6+ features to lower PHP versions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "polyfill", - "portable", - "shim" - ], - "time": "2016-05-18 14:26:46" - }, - { - "name": "symfony/polyfill-util", - "version": "v1.2.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-util.git", - "reference": "ef830ce3d218e622b221d6bfad42c751d974bf99" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-util/zipball/ef830ce3d218e622b221d6bfad42c751d974bf99", - "reference": "ef830ce3d218e622b221d6bfad42c751d974bf99", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.2-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Util\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony utilities for portability of PHP codes", - "homepage": "https://symfony.com", - "keywords": [ - "compat", - "compatibility", - "polyfill", - "shim" - ], - "time": "2016-05-18 14:26:46" + "time": "2016-11-14 01:06:16" }, { "name": "symfony/process", - "version": "v3.1.4", + "version": "v3.2.2", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "e64e93041c80e77197ace5ab9385dedb5a143697" + "reference": "350e810019fc52dd06ae844b6a6d382f8a0e8893" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/e64e93041c80e77197ace5ab9385dedb5a143697", - "reference": "e64e93041c80e77197ace5ab9385dedb5a143697", + "url": "https://api.github.com/repos/symfony/process/zipball/350e810019fc52dd06ae844b6a6d382f8a0e8893", + "reference": "350e810019fc52dd06ae844b6a6d382f8a0e8893", "shasum": "" }, "require": { @@ -2897,7 +2645,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "3.1-dev" + "dev-master": "3.2-dev" } }, "autoload": { @@ -2924,20 +2672,20 @@ ], "description": "Symfony Process Component", "homepage": "https://symfony.com", - "time": "2016-08-16 14:58:24" + "time": "2017-01-02 20:32:22" }, { "name": "symfony/routing", - "version": "v3.1.4", + "version": "v3.2.2", "source": { "type": "git", "url": "https://github.com/symfony/routing.git", - "reference": "8edf62498a1a4c57ba317664a4b698339c10cdf6" + "reference": "fda2c67d47ec801726ca888c95d701d31b27b444" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/routing/zipball/8edf62498a1a4c57ba317664a4b698339c10cdf6", - "reference": "8edf62498a1a4c57ba317664a4b698339c10cdf6", + "url": "https://api.github.com/repos/symfony/routing/zipball/fda2c67d47ec801726ca888c95d701d31b27b444", + "reference": "fda2c67d47ec801726ca888c95d701d31b27b444", "shasum": "" }, "require": { @@ -2966,7 +2714,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "3.1-dev" + "dev-master": "3.2-dev" } }, "autoload": { @@ -2999,20 +2747,20 @@ "uri", "url" ], - "time": "2016-08-16 14:58:24" + "time": "2017-01-02 20:32:22" }, { "name": "symfony/translation", - "version": "v3.1.4", + "version": "v3.2.2", "source": { "type": "git", "url": "https://github.com/symfony/translation.git", - "reference": "a35edc277513c9bc0f063ca174c36b346f974528" + "reference": "6520f3d4cce604d9dd1e86cac7af954984dd9bda" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation/zipball/a35edc277513c9bc0f063ca174c36b346f974528", - "reference": "a35edc277513c9bc0f063ca174c36b346f974528", + "url": "https://api.github.com/repos/symfony/translation/zipball/6520f3d4cce604d9dd1e86cac7af954984dd9bda", + "reference": "6520f3d4cce604d9dd1e86cac7af954984dd9bda", "shasum": "" }, "require": { @@ -3036,7 +2784,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "3.1-dev" + "dev-master": "3.2-dev" } }, "autoload": { @@ -3063,20 +2811,20 @@ ], "description": "Symfony Translation Component", "homepage": "https://symfony.com", - "time": "2016-08-05 08:37:39" + "time": "2017-01-02 20:32:22" }, { "name": "symfony/var-dumper", - "version": "v3.1.4", + "version": "v3.2.2", "source": { "type": "git", "url": "https://github.com/symfony/var-dumper.git", - "reference": "62ee73706c421654a4c840028954510277f7dfc8" + "reference": "b54b23f9a19b465e76fdaac0f6732410467c83b2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-dumper/zipball/62ee73706c421654a4c840028954510277f7dfc8", - "reference": "62ee73706c421654a4c840028954510277f7dfc8", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/b54b23f9a19b465e76fdaac0f6732410467c83b2", + "reference": "b54b23f9a19b465e76fdaac0f6732410467c83b2", "shasum": "" }, "require": { @@ -3092,7 +2840,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "3.1-dev" + "dev-master": "3.2-dev" } }, "autoload": { @@ -3126,7 +2874,54 @@ "debug", "dump" ], - "time": "2016-08-31 09:05:42" + "time": "2017-01-03 08:53:57" + }, + { + "name": "tijsverkoyen/css-to-inline-styles", + "version": "2.2.0", + "source": { + "type": "git", + "url": "https://github.com/tijsverkoyen/CssToInlineStyles.git", + "reference": "ab03919dfd85a74ae0372f8baf9f3c7d5c03b04b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/tijsverkoyen/CssToInlineStyles/zipball/ab03919dfd85a74ae0372f8baf9f3c7d5c03b04b", + "reference": "ab03919dfd85a74ae0372f8baf9f3c7d5c03b04b", + "shasum": "" + }, + "require": { + "php": "^5.5 || ^7", + "symfony/css-selector": "^2.7|~3.0" + }, + "require-dev": { + "phpunit/phpunit": "~4.8|5.1.*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "TijsVerkoyen\\CssToInlineStyles\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Tijs Verkoyen", + "email": "css_to_inline_styles@verkoyen.eu", + "role": "Developer" + } + ], + "description": "CssToInlineStyles is a class that enables you to convert HTML-pages/files into HTML-pages/files with inline styles. This is very useful when you're sending emails.", + "homepage": "https://github.com/tijsverkoyen/CssToInlineStyles", + "time": "2016-09-20 12:50:39" }, { "name": "vlucas/phpdotenv", @@ -3329,16 +3124,16 @@ }, { "name": "mockery/mockery", - "version": "0.9.5", + "version": "0.9.7", "source": { "type": "git", "url": "https://github.com/padraic/mockery.git", - "reference": "4db079511a283e5aba1b3c2fb19037c645e70fc2" + "reference": "4de7969f4664da3cef1ccd83866c9f59378c3371" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/padraic/mockery/zipball/4db079511a283e5aba1b3c2fb19037c645e70fc2", - "reference": "4db079511a283e5aba1b3c2fb19037c645e70fc2", + "url": "https://api.github.com/repos/padraic/mockery/zipball/4de7969f4664da3cef1ccd83866c9f59378c3371", + "reference": "4de7969f4664da3cef1ccd83866c9f59378c3371", "shasum": "" }, "require": { @@ -3390,20 +3185,20 @@ "test double", "testing" ], - "time": "2016-05-22 21:52:33" + "time": "2016-12-19 14:50:55" }, { "name": "myclabs/deep-copy", - "version": "1.5.4", + "version": "1.5.5", "source": { "type": "git", "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "ea74994a3dc7f8d2f65a06009348f2d63c81e61f" + "reference": "399c1f9781e222f6eb6cc238796f5200d1b7f108" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/ea74994a3dc7f8d2f65a06009348f2d63c81e61f", - "reference": "ea74994a3dc7f8d2f65a06009348f2d63c81e61f", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/399c1f9781e222f6eb6cc238796f5200d1b7f108", + "reference": "399c1f9781e222f6eb6cc238796f5200d1b7f108", "shasum": "" }, "require": { @@ -3432,7 +3227,7 @@ "object", "object graph" ], - "time": "2016-09-16 13:37:59" + "time": "2016-10-31 17:19:45" }, { "name": "phpdocumentor/reflection-common", @@ -3490,16 +3285,16 @@ }, { "name": "phpdocumentor/reflection-docblock", - "version": "3.1.0", + "version": "3.1.1", "source": { "type": "git", "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", - "reference": "9270140b940ff02e58ec577c237274e92cd40cdd" + "reference": "8331b5efe816ae05461b7ca1e721c01b46bafb3e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/9270140b940ff02e58ec577c237274e92cd40cdd", - "reference": "9270140b940ff02e58ec577c237274e92cd40cdd", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/8331b5efe816ae05461b7ca1e721c01b46bafb3e", + "reference": "8331b5efe816ae05461b7ca1e721c01b46bafb3e", "shasum": "" }, "require": { @@ -3531,20 +3326,20 @@ } ], "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", - "time": "2016-06-10 09:48:41" + "time": "2016-09-30 07:12:33" }, { "name": "phpdocumentor/type-resolver", - "version": "0.2", + "version": "0.2.1", "source": { "type": "git", "url": "https://github.com/phpDocumentor/TypeResolver.git", - "reference": "b39c7a5b194f9ed7bd0dd345c751007a41862443" + "reference": "e224fb2ea2fba6d3ad6fdaef91cd09a172155ccb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/b39c7a5b194f9ed7bd0dd345c751007a41862443", - "reference": "b39c7a5b194f9ed7bd0dd345c751007a41862443", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/e224fb2ea2fba6d3ad6fdaef91cd09a172155ccb", + "reference": "e224fb2ea2fba6d3ad6fdaef91cd09a172155ccb", "shasum": "" }, "require": { @@ -3578,20 +3373,20 @@ "email": "me@mikevanriel.com" } ], - "time": "2016-06-10 07:14:17" + "time": "2016-11-25 06:54:22" }, { "name": "phpspec/prophecy", - "version": "v1.6.1", + "version": "v1.6.2", "source": { "type": "git", "url": "https://github.com/phpspec/prophecy.git", - "reference": "58a8137754bc24b25740d4281399a4a3596058e0" + "reference": "6c52c2722f8460122f96f86346600e1077ce22cb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpspec/prophecy/zipball/58a8137754bc24b25740d4281399a4a3596058e0", - "reference": "58a8137754bc24b25740d4281399a4a3596058e0", + "url": "https://api.github.com/repos/phpspec/prophecy/zipball/6c52c2722f8460122f96f86346600e1077ce22cb", + "reference": "6c52c2722f8460122f96f86346600e1077ce22cb", "shasum": "" }, "require": { @@ -3599,10 +3394,11 @@ "php": "^5.3|^7.0", "phpdocumentor/reflection-docblock": "^2.0|^3.0.2", "sebastian/comparator": "^1.1", - "sebastian/recursion-context": "^1.0" + "sebastian/recursion-context": "^1.0|^2.0" }, "require-dev": { - "phpspec/phpspec": "^2.0" + "phpspec/phpspec": "^2.0", + "phpunit/phpunit": "^4.8 || ^5.6.5" }, "type": "library", "extra": { @@ -3640,20 +3436,20 @@ "spy", "stub" ], - "time": "2016-06-07 08:13:47" + "time": "2016-11-21 14:58:47" }, { "name": "phpunit/php-code-coverage", - "version": "4.0.1", + "version": "4.0.5", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "5f3f7e736d6319d5f1fc402aff8b026da26709a3" + "reference": "c19cfc7cbb0e9338d8c469c7eedecc2a428b0971" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/5f3f7e736d6319d5f1fc402aff8b026da26709a3", - "reference": "5f3f7e736d6319d5f1fc402aff8b026da26709a3", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/c19cfc7cbb0e9338d8c469c7eedecc2a428b0971", + "reference": "c19cfc7cbb0e9338d8c469c7eedecc2a428b0971", "shasum": "" }, "require": { @@ -3703,20 +3499,20 @@ "testing", "xunit" ], - "time": "2016-07-26 14:39:29" + "time": "2017-01-20 15:06:43" }, { "name": "phpunit/php-file-iterator", - "version": "1.4.1", + "version": "1.4.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-file-iterator.git", - "reference": "6150bf2c35d3fc379e50c7602b75caceaa39dbf0" + "reference": "3cc8f69b3028d0f96a9078e6295d86e9bf019be5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/6150bf2c35d3fc379e50c7602b75caceaa39dbf0", - "reference": "6150bf2c35d3fc379e50c7602b75caceaa39dbf0", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/3cc8f69b3028d0f96a9078e6295d86e9bf019be5", + "reference": "3cc8f69b3028d0f96a9078e6295d86e9bf019be5", "shasum": "" }, "require": { @@ -3750,7 +3546,7 @@ "filesystem", "iterator" ], - "time": "2015-06-21 13:08:43" + "time": "2016-10-03 07:40:28" }, { "name": "phpunit/php-text-template", @@ -3839,16 +3635,16 @@ }, { "name": "phpunit/php-token-stream", - "version": "1.4.8", + "version": "1.4.9", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-token-stream.git", - "reference": "3144ae21711fb6cac0b1ab4cbe63b75ce3d4e8da" + "reference": "3b402f65a4cc90abf6e1104e388b896ce209631b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/3144ae21711fb6cac0b1ab4cbe63b75ce3d4e8da", - "reference": "3144ae21711fb6cac0b1ab4cbe63b75ce3d4e8da", + "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/3b402f65a4cc90abf6e1104e388b896ce209631b", + "reference": "3b402f65a4cc90abf6e1104e388b896ce209631b", "shasum": "" }, "require": { @@ -3884,20 +3680,20 @@ "keywords": [ "tokenizer" ], - "time": "2015-09-15 10:49:45" + "time": "2016-11-15 14:06:22" }, { "name": "phpunit/phpunit", - "version": "5.5.5", + "version": "5.7.6", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "a57126dc681b08289fef6ac96a48e30656f84350" + "reference": "caf8141b89691498d91aaac6c82e9cd5f685ae86" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/a57126dc681b08289fef6ac96a48e30656f84350", - "reference": "a57126dc681b08289fef6ac96a48e30656f84350", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/caf8141b89691498d91aaac6c82e9cd5f685ae86", + "reference": "caf8141b89691498d91aaac6c82e9cd5f685ae86", "shasum": "" }, "require": { @@ -3908,18 +3704,18 @@ "ext-xml": "*", "myclabs/deep-copy": "~1.3", "php": "^5.6 || ^7.0", - "phpspec/prophecy": "^1.3.1", - "phpunit/php-code-coverage": "^4.0.1", + "phpspec/prophecy": "^1.6.2", + "phpunit/php-code-coverage": "^4.0.4", "phpunit/php-file-iterator": "~1.4", "phpunit/php-text-template": "~1.2", "phpunit/php-timer": "^1.0.6", "phpunit/phpunit-mock-objects": "^3.2", - "sebastian/comparator": "~1.1", + "sebastian/comparator": "~1.2.2", "sebastian/diff": "~1.2", - "sebastian/environment": "^1.3 || ^2.0", - "sebastian/exporter": "~1.2", - "sebastian/global-state": "~1.0", - "sebastian/object-enumerator": "~1.0", + "sebastian/environment": "^1.3.4 || ^2.0", + "sebastian/exporter": "~2.0", + "sebastian/global-state": "^1.0 || ^2.0", + "sebastian/object-enumerator": "~2.0", "sebastian/resource-operations": "~1.0", "sebastian/version": "~1.0|~2.0", "symfony/yaml": "~2.1|~3.0" @@ -3931,7 +3727,6 @@ "ext-pdo": "*" }, "suggest": { - "ext-tidy": "*", "ext-xdebug": "*", "phpunit/php-invoker": "~1.1" }, @@ -3941,7 +3736,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "5.5.x-dev" + "dev-master": "5.7.x-dev" } }, "autoload": { @@ -3967,27 +3762,27 @@ "testing", "xunit" ], - "time": "2016-09-21 14:40:13" + "time": "2017-01-22 08:39:59" }, { "name": "phpunit/phpunit-mock-objects", - "version": "3.2.7", + "version": "3.4.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git", - "reference": "546898a2c0c356ef2891b39dd7d07f5d82c8ed0a" + "reference": "3ab72b65b39b491e0c011e2e09bb2206c2aa8e24" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/546898a2c0c356ef2891b39dd7d07f5d82c8ed0a", - "reference": "546898a2c0c356ef2891b39dd7d07f5d82c8ed0a", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/3ab72b65b39b491e0c011e2e09bb2206c2aa8e24", + "reference": "3ab72b65b39b491e0c011e2e09bb2206c2aa8e24", "shasum": "" }, "require": { "doctrine/instantiator": "^1.0.2", "php": "^5.6 || ^7.0", "phpunit/php-text-template": "^1.2", - "sebastian/exporter": "^1.2" + "sebastian/exporter": "^1.2 || ^2.0" }, "conflict": { "phpunit/phpunit": "<5.4.0" @@ -4026,7 +3821,7 @@ "mock", "xunit" ], - "time": "2016-09-06 16:07:45" + "time": "2016-12-08 20:27:08" }, { "name": "sebastian/code-unit-reverse-lookup", @@ -4075,22 +3870,22 @@ }, { "name": "sebastian/comparator", - "version": "1.2.0", + "version": "1.2.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "937efb279bd37a375bcadf584dec0726f84dbf22" + "reference": "6a1ed12e8b2409076ab22e3897126211ff8b1f7f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/937efb279bd37a375bcadf584dec0726f84dbf22", - "reference": "937efb279bd37a375bcadf584dec0726f84dbf22", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/6a1ed12e8b2409076ab22e3897126211ff8b1f7f", + "reference": "6a1ed12e8b2409076ab22e3897126211ff8b1f7f", "shasum": "" }, "require": { "php": ">=5.3.3", "sebastian/diff": "~1.2", - "sebastian/exporter": "~1.2" + "sebastian/exporter": "~1.2 || ~2.0" }, "require-dev": { "phpunit/phpunit": "~4.4" @@ -4135,7 +3930,7 @@ "compare", "equality" ], - "time": "2015-07-26 15:48:44" + "time": "2016-11-19 09:18:40" }, { "name": "sebastian/diff", @@ -4191,28 +3986,28 @@ }, { "name": "sebastian/environment", - "version": "1.3.8", + "version": "2.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "be2c607e43ce4c89ecd60e75c6a85c126e754aea" + "reference": "5795ffe5dc5b02460c3e34222fee8cbe245d8fac" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/be2c607e43ce4c89ecd60e75c6a85c126e754aea", - "reference": "be2c607e43ce4c89ecd60e75c6a85c126e754aea", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/5795ffe5dc5b02460c3e34222fee8cbe245d8fac", + "reference": "5795ffe5dc5b02460c3e34222fee8cbe245d8fac", "shasum": "" }, "require": { - "php": "^5.3.3 || ^7.0" + "php": "^5.6 || ^7.0" }, "require-dev": { - "phpunit/phpunit": "^4.8 || ^5.0" + "phpunit/phpunit": "^5.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.3.x-dev" + "dev-master": "2.0.x-dev" } }, "autoload": { @@ -4237,25 +4032,25 @@ "environment", "hhvm" ], - "time": "2016-08-18 05:49:44" + "time": "2016-11-26 07:53:53" }, { "name": "sebastian/exporter", - "version": "1.2.2", + "version": "2.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "42c4c2eec485ee3e159ec9884f95b431287edde4" + "reference": "ce474bdd1a34744d7ac5d6aad3a46d48d9bac4c4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/42c4c2eec485ee3e159ec9884f95b431287edde4", - "reference": "42c4c2eec485ee3e159ec9884f95b431287edde4", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/ce474bdd1a34744d7ac5d6aad3a46d48d9bac4c4", + "reference": "ce474bdd1a34744d7ac5d6aad3a46d48d9bac4c4", "shasum": "" }, "require": { "php": ">=5.3.3", - "sebastian/recursion-context": "~1.0" + "sebastian/recursion-context": "~2.0" }, "require-dev": { "ext-mbstring": "*", @@ -4264,7 +4059,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.3.x-dev" + "dev-master": "2.0.x-dev" } }, "autoload": { @@ -4304,7 +4099,7 @@ "export", "exporter" ], - "time": "2016-06-17 09:04:28" + "time": "2016-11-19 08:54:04" }, { "name": "sebastian/global-state", @@ -4359,21 +4154,21 @@ }, { "name": "sebastian/object-enumerator", - "version": "1.0.0", + "version": "2.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/object-enumerator.git", - "reference": "d4ca2fb70344987502567bc50081c03e6192fb26" + "reference": "96f8a3f257b69e8128ad74d3a7fd464bcbaa3b35" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/d4ca2fb70344987502567bc50081c03e6192fb26", - "reference": "d4ca2fb70344987502567bc50081c03e6192fb26", + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/96f8a3f257b69e8128ad74d3a7fd464bcbaa3b35", + "reference": "96f8a3f257b69e8128ad74d3a7fd464bcbaa3b35", "shasum": "" }, "require": { "php": ">=5.6", - "sebastian/recursion-context": "~1.0" + "sebastian/recursion-context": "~2.0" }, "require-dev": { "phpunit/phpunit": "~5" @@ -4381,7 +4176,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0.x-dev" + "dev-master": "2.0.x-dev" } }, "autoload": { @@ -4401,20 +4196,20 @@ ], "description": "Traverses array structures and object graphs to enumerate all referenced objects", "homepage": "https://github.com/sebastianbergmann/object-enumerator/", - "time": "2016-01-28 13:25:10" + "time": "2016-11-19 07:35:10" }, { "name": "sebastian/recursion-context", - "version": "1.0.2", + "version": "2.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/recursion-context.git", - "reference": "913401df809e99e4f47b27cdd781f4a258d58791" + "reference": "2c3ba150cbec723aa057506e73a8d33bdb286c9a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/913401df809e99e4f47b27cdd781f4a258d58791", - "reference": "913401df809e99e4f47b27cdd781f4a258d58791", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/2c3ba150cbec723aa057506e73a8d33bdb286c9a", + "reference": "2c3ba150cbec723aa057506e73a8d33bdb286c9a", "shasum": "" }, "require": { @@ -4426,7 +4221,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0.x-dev" + "dev-master": "2.0.x-dev" } }, "autoload": { @@ -4454,7 +4249,7 @@ ], "description": "Provides functionality to recursively process PHP variables", "homepage": "http://www.github.com/sebastianbergmann/recursion-context", - "time": "2015-11-11 19:50:13" + "time": "2016-11-19 07:33:16" }, { "name": "sebastian/resource-operations", @@ -4500,16 +4295,16 @@ }, { "name": "sebastian/version", - "version": "2.0.0", + "version": "2.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/version.git", - "reference": "c829badbd8fdf16a0bad8aa7fa7971c029f1b9c5" + "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c829badbd8fdf16a0bad8aa7fa7971c029f1b9c5", - "reference": "c829badbd8fdf16a0bad8aa7fa7971c029f1b9c5", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/99732be0ddb3361e16ad77b68ba41efc8e979019", + "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019", "shasum": "" }, "require": { @@ -4539,138 +4334,35 @@ ], "description": "Library that helps with managing the version number of Git-hosted PHP projects", "homepage": "https://github.com/sebastianbergmann/version", - "time": "2016-02-04 12:56:52" - }, - { - "name": "symfony/css-selector", - "version": "v3.1.4", - "source": { - "type": "git", - "url": "https://github.com/symfony/css-selector.git", - "reference": "2851e1932d77ce727776154d659b232d061e816a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/css-selector/zipball/2851e1932d77ce727776154d659b232d061e816a", - "reference": "2851e1932d77ce727776154d659b232d061e816a", - "shasum": "" - }, - "require": { - "php": ">=5.5.9" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.1-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Component\\CssSelector\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Jean-François Simon", - "email": "jeanfrancois.simon@sensiolabs.com" - }, - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony CssSelector Component", - "homepage": "https://symfony.com", - "time": "2016-06-29 05:41:56" - }, - { - "name": "symfony/dom-crawler", - "version": "v3.1.4", - "source": { - "type": "git", - "url": "https://github.com/symfony/dom-crawler.git", - "reference": "bb7395e8b1db3654de82b9f35d019958276de4d7" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/bb7395e8b1db3654de82b9f35d019958276de4d7", - "reference": "bb7395e8b1db3654de82b9f35d019958276de4d7", - "shasum": "" - }, - "require": { - "php": ">=5.5.9", - "symfony/polyfill-mbstring": "~1.0" - }, - "require-dev": { - "symfony/css-selector": "~2.8|~3.0" - }, - "suggest": { - "symfony/css-selector": "" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.1-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Component\\DomCrawler\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony DomCrawler Component", - "homepage": "https://symfony.com", - "time": "2016-08-05 08:37:39" + "time": "2016-10-03 07:35:21" }, { "name": "symfony/yaml", - "version": "v3.1.4", + "version": "v3.2.2", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "f291ed25eb1435bddbe8a96caaef16469c2a092d" + "reference": "50eadbd7926e31842893c957eca362b21592a97d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/f291ed25eb1435bddbe8a96caaef16469c2a092d", - "reference": "f291ed25eb1435bddbe8a96caaef16469c2a092d", + "url": "https://api.github.com/repos/symfony/yaml/zipball/50eadbd7926e31842893c957eca362b21592a97d", + "reference": "50eadbd7926e31842893c957eca362b21592a97d", "shasum": "" }, "require": { "php": ">=5.5.9" }, + "require-dev": { + "symfony/console": "~2.8|~3.0" + }, + "suggest": { + "symfony/console": "For validating YAML files using the lint command" + }, "type": "library", "extra": { "branch-alias": { - "dev-master": "3.1-dev" + "dev-master": "3.2-dev" } }, "autoload": { @@ -4697,24 +4389,24 @@ ], "description": "Symfony Yaml Component", "homepage": "https://symfony.com", - "time": "2016-09-02 02:12:52" + "time": "2017-01-03 13:51:32" }, { "name": "webmozart/assert", - "version": "1.1.0", + "version": "1.2.0", "source": { "type": "git", "url": "https://github.com/webmozart/assert.git", - "reference": "bb2d123231c095735130cc8f6d31385a44c7b308" + "reference": "2db61e59ff05fe5126d152bd0655c9ea113e550f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/webmozart/assert/zipball/bb2d123231c095735130cc8f6d31385a44c7b308", - "reference": "bb2d123231c095735130cc8f6d31385a44c7b308", + "url": "https://api.github.com/repos/webmozart/assert/zipball/2db61e59ff05fe5126d152bd0655c9ea113e550f", + "reference": "2db61e59ff05fe5126d152bd0655c9ea113e550f", "shasum": "" }, "require": { - "php": "^5.3.3|^7.0" + "php": "^5.3.3 || ^7.0" }, "require-dev": { "phpunit/phpunit": "^4.6", @@ -4723,7 +4415,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.2-dev" + "dev-master": "1.3-dev" } }, "autoload": { @@ -4747,7 +4439,7 @@ "check", "validate" ], - "time": "2016-08-09 15:02:57" + "time": "2016-11-23 20:04:58" } ], "aliases": [], diff --git a/database/factories/ModelFactory.php b/database/factories/ModelFactory.php index 3820d5b59..43e214386 100644 --- a/database/factories/ModelFactory.php +++ b/database/factories/ModelFactory.php @@ -59,4 +59,14 @@ $factory->define(BookStack\Tag::class, function ($faker) { 'name' => $faker->city, 'value' => $faker->sentence(3) ]; +}); + +$factory->define(BookStack\Image::class, function ($faker) { + return [ + 'name' => $faker->slug . '.jpg', + 'url' => $faker->url, + 'path' => $faker->url, + 'type' => 'gallery', + 'uploaded_to' => 0 + ]; }); \ No newline at end of file diff --git a/database/migrations/2017_01_21_163556_create_cache_table.php b/database/migrations/2017_01_21_163556_create_cache_table.php new file mode 100644 index 000000000..1f7761c2b --- /dev/null +++ b/database/migrations/2017_01_21_163556_create_cache_table.php @@ -0,0 +1,32 @@ +string('key')->unique(); + $table->text('value'); + $table->integer('expiration'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('cache'); + } +} diff --git a/database/migrations/2017_01_21_163602_create_sessions_table.php b/database/migrations/2017_01_21_163602_create_sessions_table.php new file mode 100644 index 000000000..56e76d6df --- /dev/null +++ b/database/migrations/2017_01_21_163602_create_sessions_table.php @@ -0,0 +1,35 @@ +string('id')->unique(); + $table->integer('user_id')->nullable(); + $table->string('ip_address', 45)->nullable(); + $table->text('user_agent')->nullable(); + $table->text('payload'); + $table->integer('last_activity'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('sessions'); + } +} diff --git a/package.json b/package.json index ec5911b93..b0805c918 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,9 @@ "laravel-elixir": "^6.0.0-11", "laravel-elixir-browserify-official": "^0.1.3", "marked": "^0.3.5", - "moment": "^2.12.0", - "zeroclipboard": "^2.2.0" + "moment": "^2.12.0" + }, + "dependencies": { + "clipboard": "^1.5.16" } } diff --git a/public/ZeroClipboard.swf b/public/ZeroClipboard.swf deleted file mode 100644 index 8bad6a3e3..000000000 Binary files a/public/ZeroClipboard.swf and /dev/null differ diff --git a/readme.md b/readme.md index fa5c48fe0..63d43e4b7 100644 --- a/readme.md +++ b/readme.md @@ -40,13 +40,19 @@ php artisan db:seed --class=DummyContentSeeder --database=mysql_testing Once done you can run `phpunit` in the application root directory to run all tests. -## Website and Docs +## Translations -The website and project docs are currently stored in the [BookStackApp/website](https://github.com/BookStackApp/website) repo. The docs are stored as markdown files in the `resources/docs` folder +As part of BookStack v0.14 support for translations has been built in. All text strings can be found in the `resources/lang` folder where each language option has its own folder. To add a new language you should copy the `en` folder to an new folder (eg. `fr` for french) then go through and translate all text strings in those files, leaving the keys and file-names intact. If a language string is missing then the `en` translation will be used. To show the language option in the user preferences language drop-down you will need to add your language to the options found at the bottom of the `resources/lang/en/settings.php` file. A system-wide language can also be set in the `.env` file like so: `APP_LANG=en`. + + Some strings have colon-prefixed variables in such as `:userName`. Leave these values as they are as they will be replaced at run-time. + +## Website, Docs & Blog + +The website project docs & Blog can be found in the [BookStackApp/website](https://github.com/BookStackApp/website) repo. ## License -BookStack is provided under the MIT License. +The BookStack source is provided under the MIT License. ## Attribution diff --git a/resources/assets/js/global.js b/resources/assets/js/global.js index 94462ed64..650919f85 100644 --- a/resources/assets/js/global.js +++ b/resources/assets/js/global.js @@ -61,10 +61,9 @@ Controllers(ngApp, window.Events); // Smooth scrolling jQuery.fn.smoothScrollTo = function () { if (this.length === 0) return; - let scrollElem = document.documentElement.scrollTop === 0 ? document.body : document.documentElement; - $(scrollElem).animate({ + $('html, body').animate({ scrollTop: this.offset().top - 60 // Adjust to change final scroll position top margin - }, 800); // Adjust to change animations speed (ms) + }, 300); // Adjust to change animations speed (ms) return this; }; diff --git a/resources/assets/js/pages/page-form.js b/resources/assets/js/pages/page-form.js index e1c0cfe8f..0f44b3d09 100644 --- a/resources/assets/js/pages/page-form.js +++ b/resources/assets/js/pages/page-form.js @@ -77,7 +77,7 @@ export default function() { extended_valid_elements: 'pre[*]', automatic_uploads: false, valid_children: "-div[p|pre|h1|h2|h3|h4|h5|h6|blockquote]", - plugins: "image table textcolor paste link fullscreen imagetools code customhr autosave lists", + plugins: "image table textcolor paste link autolink fullscreen imagetools code customhr autosave lists", imagetools_toolbar: 'imageoptions', toolbar: "undo redo | styleselect | bold italic underline strikethrough superscript subscript | forecolor backcolor | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | table image-insert link hr | removeformat code fullscreen", content_style: "body {padding-left: 15px !important; padding-right: 15px !important; margin:0!important; margin-left:auto!important;margin-right:auto!important;}", diff --git a/resources/assets/js/pages/page-show.js b/resources/assets/js/pages/page-show.js index 0cdde790d..0f45e1987 100644 --- a/resources/assets/js/pages/page-show.js +++ b/resources/assets/js/pages/page-show.js @@ -1,13 +1,16 @@ "use strict"; // Configure ZeroClipboard -import zeroClipBoard from "zeroclipboard"; +import Clipboard from "clipboard"; export default window.setupPageShow = function (pageId) { // Set up pointer let $pointer = $('#pointer').detach(); + let pointerShowing = false; let $pointerInner = $pointer.children('div.pointer').first(); let isSelection = false; + let pointerModeLink = true; + let pointerSectionId = ''; // Select all contents on input click $pointer.on('click', 'input', function (e) { @@ -15,19 +18,34 @@ export default window.setupPageShow = function (pageId) { e.stopPropagation(); }); - // Set up copy-to-clipboard - zeroClipBoard.config({ - swfPath: window.baseUrl('/ZeroClipboard.swf') + // Pointer mode toggle + $pointer.on('click', 'span.icon', event => { + let $icon = $(event.currentTarget); + pointerModeLink = !pointerModeLink; + $icon.html(pointerModeLink ? '' : ''); + updatePointerContent(); }); - new zeroClipBoard($pointer.find('button').first()[0]); + + // Set up clipboard + let clipboard = new Clipboard('#pointer button'); // Hide pointer when clicking away - $(document.body).find('*').on('click focus', function (e) { - if (!isSelection) { - $pointer.detach(); - } + $(document.body).find('*').on('click focus', event => { + if (!pointerShowing || isSelection) return; + let target = $(event.target); + if (target.is('.zmdi') || $(event.target).closest('#pointer').length === 1) return; + + $pointer.detach(); + pointerShowing = false; }); + function updatePointerContent() { + let inputText = pointerModeLink ? window.baseUrl(`/link/${pageId}#${pointerSectionId}`) : `{{@${pageId}#${pointerSectionId}}}`; + if (pointerModeLink && inputText.indexOf('http') !== 0) inputText = window.location.protocol + "//" + window.location.host + inputText; + + $pointer.find('input').val(inputText); + } + // Show pointer when selecting a single block of tagged content $('.page-content [id^="bkmrk"]').on('mouseup keyup', function (e) { e.stopPropagation(); @@ -36,12 +54,12 @@ export default window.setupPageShow = function (pageId) { // Show pointer and set link let $elem = $(this); - let link = window.baseUrl('/link/' + pageId + '#' + $elem.attr('id')); - if (link.indexOf('http') !== 0) link = window.location.protocol + "//" + window.location.host + link; - $pointer.find('input').val(link); - $pointer.find('button').first().attr('data-clipboard-text', link); + pointerSectionId = $elem.attr('id'); + updatePointerContent(); + $elem.before($pointer); $pointer.show(); + pointerShowing = true; // Set pointer to sit near mouse-up position let pointerLeftOffset = (e.pageX - $elem.offset().left - ($pointerInner.width() / 2)); @@ -57,10 +75,12 @@ export default window.setupPageShow = function (pageId) { // Go to, and highlight if necessary, the specified text. function goToText(text) { - let idElem = $('.page-content #' + text).first(); - if (idElem.length !== 0) { - idElem.smoothScrollTo(); - idElem.css('background-color', 'rgba(244, 249, 54, 0.25)'); + let idElem = document.getElementById(text); + $('.page-content [data-highlighted]').attr('data-highlighted', '').css('background-color', ''); + if (idElem !== null) { + let $idElem = $(idElem); + let color = $('#custom-styles').attr('data-color-light'); + $idElem.css('background-color', color).attr('data-highlighted', 'true').smoothScrollTo(); } else { $('.page-content').find(':contains("' + text + '")').smoothScrollTo(); } @@ -72,6 +92,11 @@ export default window.setupPageShow = function (pageId) { goToText(text); } + // Sidebar page nav click event + $('.sidebar-page-nav').on('click', 'a', event => { + goToText(event.target.getAttribute('href').substr(1)); + }); + // Make the book-tree sidebar stick in view on scroll let $window = $(window); let $bookTree = $(".book-tree"); diff --git a/resources/assets/sass/_blocks.scss b/resources/assets/sass/_blocks.scss index 7eb595d36..a2023aa37 100644 --- a/resources/assets/sass/_blocks.scss +++ b/resources/assets/sass/_blocks.scss @@ -136,9 +136,6 @@ background-color: #EEE; padding: $-s; display: block; - > * { - display: inline-block; - } &:before { font-family: 'Material-Design-Iconic-Font'; padding-right: $-s; diff --git a/resources/assets/sass/_buttons.scss b/resources/assets/sass/_buttons.scss index 5de889673..791a5bb72 100644 --- a/resources/assets/sass/_buttons.scss +++ b/resources/assets/sass/_buttons.scss @@ -108,5 +108,4 @@ $button-border-radius: 2px; cursor: default; box-shadow: none; } -} - +} \ No newline at end of file diff --git a/resources/assets/sass/_components.scss b/resources/assets/sass/_components.scss index c8fd8bcfa..5328057d9 100644 --- a/resources/assets/sass/_components.scss +++ b/resources/assets/sass/_components.scss @@ -70,9 +70,6 @@ body.flexbox-support #entity-selector-wrap .popup-body .form-group { #entity-selector-wrap .popup-body .form-group { margin: 0; } -//body.ie #entity-selector-wrap .popup-body .form-group { -// min-height: 60vh; -//} .image-manager-body { min-height: 70vh; diff --git a/resources/assets/sass/_pages.scss b/resources/assets/sass/_pages.scss index 0052a3319..e5334c69c 100755 --- a/resources/assets/sass/_pages.scss +++ b/resources/assets/sass/_pages.scss @@ -138,6 +138,10 @@ font-size: 18px; padding-top: 4px; } + span.icon { + cursor: pointer; + user-select: none; + } .button { line-height: 1; margin: 0 0 0 -4px; diff --git a/resources/assets/sass/_text.scss b/resources/assets/sass/_text.scss index dd2f32e1c..74eb6875a 100644 --- a/resources/assets/sass/_text.scss +++ b/resources/assets/sass/_text.scss @@ -175,6 +175,7 @@ pre code { background-color: transparent; border: 0; font-size: 1em; + display: block; } /* * Text colors diff --git a/resources/assets/sass/export-styles.scss b/resources/assets/sass/export-styles.scss index 60450f3e2..7e1ab4e9e 100644 --- a/resources/assets/sass/export-styles.scss +++ b/resources/assets/sass/export-styles.scss @@ -1,4 +1,4 @@ -//@import "reset"; +@import "reset"; @import "variables"; @import "mixins"; @import "html"; diff --git a/resources/lang/en/entities.php b/resources/lang/en/entities.php index 033d9614e..109b6ee2a 100644 --- a/resources/lang/en/entities.php +++ b/resources/lang/en/entities.php @@ -89,6 +89,7 @@ return [ * Chapters */ 'chapter' => 'Chapter', + 'chapters' => 'Chapters', 'chapters_popular' => 'Popular Chapters', 'chapters_new' => 'New Chapter', 'chapters_create' => 'Create New Chapter', diff --git a/resources/lang/en/settings.php b/resources/lang/en/settings.php index e61df19d9..ed8a0db43 100644 --- a/resources/lang/en/settings.php +++ b/resources/lang/en/settings.php @@ -1,13 +1,13 @@ 'Settings', 'settings_save' => 'Save Settings', 'settings_save_success' => 'Settings saved', @@ -92,7 +92,7 @@ return [ 'users_password_warning' => 'Only fill the below if you would like to change your password:', 'users_system_public' => 'This user represents any guest users that visit your instance. It cannot be used to log in but is assigned automatically.', 'users_delete' => 'Delete User', - 'users_delete_named' => 'Delete ser :userName', + 'users_delete_named' => 'Delete user :userName', 'users_delete_warning' => 'This will fully delete this user with the name \':userName\' from the system.', 'users_delete_confirm' => 'Are you sure you want to delete this user?', 'users_delete_success' => 'Users successfully removed', @@ -101,40 +101,23 @@ return [ 'users_edit_success' => 'User successfully updated', 'users_avatar' => 'User Avatar', 'users_avatar_desc' => 'This image should be approx 256px square.', + 'users_preferred_language' => 'Preferred Language', 'users_social_accounts' => 'Social Accounts', 'users_social_accounts_info' => 'Here you can connect your other accounts for quicker and easier login. Disconnecting an account here does not previously authorized access. Revoke access from your profile settings on the connected social account.', 'users_social_connect' => 'Connect Account', 'users_social_disconnect' => 'Disconnect Account', 'users_social_connected' => ':socialAccount account was successfully attached to your profile.', 'users_social_disconnected' => ':socialAccount account was successfully disconnected from your profile.', + + // Since these labels are already localized this array does not need to be + // translated in the language-specific files. + // DELETE BELOW IF COPIED FROM EN + /////////////////////////////////// + 'language_select' => [ + 'en' => 'English', + 'de' => 'Deutsch', + 'fr' => 'Français', + 'pt_BR' => 'Português do Brasil' + ] + /////////////////////////////////// ]; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/resources/lang/fr/activities.php b/resources/lang/fr/activities.php new file mode 100644 index 000000000..32f225d5d --- /dev/null +++ b/resources/lang/fr/activities.php @@ -0,0 +1,40 @@ + 'a créé la page', + 'page_create_notification' => 'Page créée avec succès', + 'page_update' => 'a modifié la page', + 'page_update_notification' => 'Page modifiée avec succès', + 'page_delete' => 'a supprimé la page', + 'page_delete_notification' => 'Page supprimée avec succès', + 'page_restore' => 'a restauré la page', + 'page_restore_notification' => 'Page réstaurée avec succès', + 'page_move' => 'a déplacé la page', + + // Chapters + 'chapter_create' => 'a créé le chapitre', + 'chapter_create_notification' => 'Chapitre créé avec succès', + 'chapter_update' => 'a modifié le chapitre', + 'chapter_update_notification' => 'Chapitre modifié avec succès', + 'chapter_delete' => 'a supprimé le chapitre', + 'chapter_delete_notification' => 'Chapitre supprimé avec succès', + 'chapter_move' => 'a déplacé le chapitre', + + // Books + 'book_create' => 'a créé le livre', + 'book_create_notification' => 'Livre créé avec succès', + 'book_update' => 'a modifié le livre', + 'book_update_notification' => 'Livre modifié avec succès', + 'book_delete' => 'a supprimé le livre', + 'book_delete_notification' => 'Livre supprimé avec succès', + 'book_sort' => 'a réordonné le livre', + 'book_sort_notification' => 'Livre réordonné avec succès', + +]; diff --git a/resources/lang/fr/auth.php b/resources/lang/fr/auth.php new file mode 100644 index 000000000..41d051c5f --- /dev/null +++ b/resources/lang/fr/auth.php @@ -0,0 +1,74 @@ + 'Ces informations ne correspondent a aucun compte.', + 'throttle' => "Trop d'essais, veuillez réessayer dans :seconds secondes.", + + /** + * Login & Register + */ + 'sign_up' => "S'inscrire", + 'log_in' => 'Se connecter', + 'logout' => 'Se déconnecter', + + 'name' => 'Nom', + 'username' => "Nom d'utilisateur", + 'email' => 'E-mail', + 'password' => 'Mot de passe', + 'password_confirm' => 'Confirmez le mot de passe', + 'password_hint' => 'Doit faire plus de 5 caractères', + 'forgot_password' => 'Mot de passe oublié?', + 'remember_me' => 'Se souvenir de moi', + 'ldap_email_hint' => "Merci d'entrer une adresse e-mail pour ce compte", + 'create_account' => 'Créer un compte', + 'social_login' => 'Social Login', + 'social_registration' => 'Enregistrement Social', + 'social_registration_text' => "S'inscrire et se connecter avec un réseau social", + + 'register_thanks' => 'Merci pour votre enregistrement', + 'register_confirm' => 'Vérifiez vos e-mails et cliquer sur le lien de confirmation pour rejoindre :appName.', + 'registrations_disabled' => "L'inscription est désactivée pour le moment", + 'registration_email_domain_invalid' => 'Cette adresse e-mail ne peux pas adcéder à l\'application', + 'register_success' => 'Merci pour votre inscription. Vous êtes maintenant inscrit(e) et connecté(e)', + + + /** + * Password Reset + */ + 'reset_password' => 'Reset Password', + 'reset_password_send_instructions' => 'Entrez votre adresse e-mail ci-dessous et un e-mail avec un lien de réinitialisation de mot de passe vous sera envoyé', + 'reset_password_send_button' => 'Envoyer un lien de réinitialisation', + 'reset_password_sent_success' => 'Un lien de réinitialisation a été envoyé à :email.', + 'reset_password_success' => 'Votre mot de passe a été réinitialisé avec succès.', + + 'email_reset_subject' => 'Réinitialisez votre mot de passe pour :appName', + 'email_reset_text' => 'Vous recevez cet e-mail parceque nous avons reçu une demande de réinitialisation pour votre compte', + 'email_reset_not_requested' => 'Si vous n\'avez pas effectué cette demande, vous pouvez ignorer cet e-mail.', + + + /** + * Email Confirmation + */ + 'email_confirm_subject' => 'Confirmez votre adresse e-mail pour :appName', + 'email_confirm_greeting' => 'Merci d\'avoir rejoint :appName!', + 'email_confirm_text' => 'Merci de confirmer en cliquant sur le lien ci-dessous:', + 'email_confirm_action' => 'Confirmez votre adresse e-mail', + 'email_confirm_send_error' => 'La confirmation par e-mail est requise mais le système n\'a pas pu envoyer l\'e-mail. Contactez l\'administrateur système.', + 'email_confirm_success' => 'Votre adresse e-mail a été confirmée!', + 'email_confirm_resent' => 'L\'e-mail de confirmation a été ré-envoyé. Vérifiez votre boîte de récéption.', + + 'email_not_confirmed' => 'Adresse e-mail non confirmée', + 'email_not_confirmed_text' => 'Votre adresse e-mail n\'a pas été confirmée.', + 'email_not_confirmed_click_link' => 'Merci de cliquer sur le lien dans l\'e-mail qui vous a été envoyé après l\'enregistrement.', + 'email_not_confirmed_resend' => 'Si vous ne retrouvez plus l\'e-mail, vous pouvez renvoyer un e-mail de confirmation en utilisant le formulaire ci-dessous.', + 'email_not_confirmed_resend_button' => 'Renvoyez l\'e-mail de confirmation', +]; diff --git a/resources/lang/fr/common.php b/resources/lang/fr/common.php new file mode 100644 index 000000000..5eb4b8fa8 --- /dev/null +++ b/resources/lang/fr/common.php @@ -0,0 +1,58 @@ + 'Annuler', + 'confirm' => 'Confirmer', + 'back' => 'Retour', + 'save' => 'Enregistrer', + 'continue' => 'Continuer', + 'select' => 'Selectionner', + + /** + * Form Labels + */ + 'name' => 'Nom', + 'description' => 'Description', + 'role' => 'Rôle', + + /** + * Actions + */ + 'actions' => 'Actions', + 'view' => 'Voir', + 'create' => 'Créer', + 'update' => 'Modifier', + 'edit' => 'Editer', + 'sort' => 'Trier', + 'move' => 'Déplacer', + 'delete' => 'Supprimer', + 'search' => 'Chercher', + 'search_clear' => 'Réinitialiser la recherche', + 'reset' => 'Réinitialiser', + 'remove' => 'Enlever', + + + /** + * Misc + */ + 'deleted_user' => 'Utilisateur supprimé', + 'no_activity' => 'Aucune activité', + 'no_items' => 'Aucun élément', + 'back_to_top' => 'Retour en haut', + 'toggle_details' => 'Afficher les détails', + + /** + * Header + */ + 'view_profile' => 'Voir le profil', + 'edit_profile' => 'Modifier le profil', + + /** + * Email Content + */ + 'email_action_help' => 'Si vous rencontrez des problèmes pour cliquer le bouton ":actionText", copiez et collez l\'adresse ci-dessous dans votre navigateur:', + 'email_rights' => 'Tous droits réservés', +]; diff --git a/resources/lang/fr/components.php b/resources/lang/fr/components.php new file mode 100644 index 000000000..7c9c4cfc0 --- /dev/null +++ b/resources/lang/fr/components.php @@ -0,0 +1,24 @@ + 'Selectionner une image', + 'image_all' => 'Toutes', + 'image_all_title' => 'Voir toutes les images', + 'image_book_title' => 'Voir les images ajoutées à ce livre', + 'image_page_title' => 'Voir les images ajoutées à cette page', + 'image_search_hint' => 'Rechercher par nom d\'image', + 'image_uploaded' => 'Ajoutée le :uploadedDate', + 'image_load_more' => 'Charger plus', + 'image_image_name' => 'Nom de l\'image', + 'image_delete_confirm' => 'Cette image est utilisée dans les pages ci-dessous. Confirmez que vous souhaitez bien supprimer cette image.', + 'image_select_image' => 'Selectionner l\'image', + 'image_dropzone' => 'Glissez les images ici ou cliquez pour les ajouter', + 'images_deleted' => 'Images supprimées', + 'image_preview' => 'Prévisualiser l\'image', + 'image_upload_success' => 'Image ajoutée avec succès', + 'image_update_success' => 'Détails de l\'image mis à jour', + 'image_delete_success' => 'Image supprimée avec succès' +]; diff --git a/resources/lang/fr/entities.php b/resources/lang/fr/entities.php new file mode 100644 index 000000000..941259f80 --- /dev/null +++ b/resources/lang/fr/entities.php @@ -0,0 +1,225 @@ + 'Créé récemment', + 'recently_created_pages' => 'Pages créées récemment', + 'recently_updated_pages' => 'Pages mises à jour récemment', + 'recently_created_chapters' => 'Chapitres créés récemment', + 'recently_created_books' => 'Livres créés récemment', + 'recently_update' => 'Mis à jour récemment', + 'recently_viewed' => 'Vus récemment', + 'recent_activity' => 'Activité récente', + 'create_now' => 'En créer un récemment', + 'revisions' => 'Révisions', + 'meta_created' => 'Créé :timeLength', + 'meta_created_name' => 'Créé :timeLength par :user', + 'meta_updated' => 'Mis à jour :timeLength', + 'meta_updated_name' => 'Mis à jour :timeLength par :user', + 'x_pages' => ':count pages', + 'entity_select' => 'Sélectionner l\'entité', + 'images' => 'Images', + 'my_recent_drafts' => 'Mes brouillons récents', + 'my_recently_viewed' => 'Vus récemment', + 'no_pages_viewed' => 'Vous n\'avez rien visité récemment', + 'no_pages_recently_created' => 'Aucune page créée récemment', + 'no_pages_recently_updated' => 'Aucune page mise à jour récemment', + + /** + * Permissions and restrictions + */ + 'permissions' => 'Permissions', + 'permissions_intro' => 'Une fois activées ces permission prendont la priorité sur tous les sets de permissions pré-existants.', + 'permissions_enable' => 'Activer les permissions personnalisées', + 'permissions_save' => 'Enregistrer les permissions', + + /** + * Search + */ + 'search_results' => 'Résultats de recherche', + 'search_results_page' => 'Résultats de recherche des pages', + 'search_results_chapter' => 'Résultats de recherche des chapitres', + 'search_results_book' => 'Résultats de recherche des livres', + 'search_clear' => 'Réinitialiser la recherche', + 'search_view_pages' => 'Voir toutes les pages correspondantes', + 'search_view_chapters' => 'Voir tous les chapitres correspondants', + 'search_view_books' => 'Voir tous les livres correspondants', + 'search_no_pages' => 'Aucune page correspondant à cette recherche', + 'search_for_term' => 'recherche pour :term', + 'search_page_for_term' => 'Recherche de page pour :term', + 'search_chapter_for_term' => 'Recherche de chapitre pour :term', + 'search_book_for_term' => 'Recherche de livres pour :term', + + /** + * Books + */ + 'book' => 'Livre', + 'books' => 'Livres', + 'books_empty' => 'Aucun livre n\'a été créé', + 'books_popular' => 'Livres populaires', + 'books_recent' => 'Livres récents', + 'books_popular_empty' => 'Les livres les plus populaires apparaîtront ici.', + 'books_create' => 'Créer un nouveau livre', + 'books_delete' => 'Supprimer un livre', + 'books_delete_named' => 'Supprimer le livre :bookName', + 'books_delete_explain' => 'Ceci va supprimer le livre nommé \':bookName\', Tous les chapitres et pages seront supprimés.', + 'books_delete_confirmation' => 'Êtes-vous sûr(e) de vouloir supprimer ce livre?', + 'books_edit' => 'Modifier le livre', + 'books_edit_named' => 'Modifier le livre :bookName', + 'books_form_book_name' => 'Nom du livre', + 'books_save' => 'Enregistrer le livre', + 'books_permissions' => 'Permissions du livre', + 'books_permissions_updated' => 'Permissions du livre mises à jour', + 'books_empty_contents' => 'Aucune page ou chapitre n\'a été ajouté à ce livre.', + 'books_empty_create_page' => 'Créer une nouvelle page', + 'books_empty_or' => 'ou', + 'books_empty_sort_current_book' => 'Trier les pages du livre', + 'books_empty_add_chapter' => 'Ajouter un chapitre', + 'books_permissions_active' => 'Permissions personnalisées activées', + 'books_search_this' => 'Chercher dans le livre', + 'books_navigation' => 'Navigation dans le livre', + 'books_sort' => 'Trier les contenus du livre', + 'books_sort_named' => 'Trier le livre :bookName', + 'books_sort_show_other' => 'Afficher d\'autres livres', + 'books_sort_save' => 'Enregistrer l\'ordre', + + /** + * Chapters + */ + 'chapter' => 'Chapitre', + 'chapters' => 'Chapitres', + 'chapters_popular' => 'Chapitres populaires', + 'chapters_new' => 'Nouveau chapitre', + 'chapters_create' => 'Créer un nouveau chapitre', + 'chapters_delete' => 'Supprimer le chapitre', + 'chapters_delete_named' => 'Supprimer le chapitre :chapterName', + 'chapters_delete_explain' => 'Ceci va supprimer le chapitre \':chapterName\', Toutes les pages seront déplacée dans le livre parent.', + 'chapters_delete_confirm' => 'Etes-vous sûr(e) de vouloir supprimer ce chapitre?', + 'chapters_edit' => 'Modifier le chapitre', + 'chapters_edit_named' => 'Modifier le chapitre :chapterName', + 'chapters_save' => 'Enregistrer le chapitre', + 'chapters_move' => 'Déplace le chapitre', + 'chapters_move_named' => 'Déplacer le chapitre :chapterName', + 'chapter_move_success' => 'Chapitre déplacé dans :bookName', + 'chapters_permissions' => 'Permissions du chapitre', + 'chapters_empty' => 'Il n\'y a pas de pages dans ce chapitre actuellement.', + 'chapters_permissions_active' => 'Permissions du chapitre activées', + 'chapters_permissions_success' => 'Permissions du chapitres mises à jour', + + /** + * Pages + */ + 'page' => 'Page', + 'pages' => 'Pages', + 'pages_popular' => 'Pages populaires', + 'pages_new' => 'Nouvelle page', + 'pages_attachments' => 'Fichiers joints', + 'pages_navigation' => 'Navigation des pages', + 'pages_delete' => 'Supprimer la page', + 'pages_delete_named' => 'Supprimer la page :pageName', + 'pages_delete_draft_named' => 'supprimer le brouillon de la page :pageName', + 'pages_delete_draft' => 'Supprimer le brouillon', + 'pages_delete_success' => 'Page supprimée', + 'pages_delete_draft_success' => 'Brouillon supprimé', + 'pages_delete_confirm' => 'Êtes-vous sûr(e) de vouloir supprimer cette page?', + 'pages_delete_draft_confirm' => 'Êtes-vous sûr(e) de vouloir supprimer ce brouillon?', + 'pages_editing_named' => 'Modification de la page :pageName', + 'pages_edit_toggle_header' => 'Afficher/cacher l\'en-tête', + 'pages_edit_save_draft' => 'Enregistrer le brouillon', + 'pages_edit_draft' => 'Modifier le brouillon', + 'pages_editing_draft' => 'Modification du brouillon', + 'pages_editing_page' => 'Modification de la page', + 'pages_edit_draft_save_at' => 'Brouillon sauvé le ', + 'pages_edit_delete_draft' => 'Supprimer le brouillon', + 'pages_edit_discard_draft' => 'Ecarter le brouillon', + 'pages_edit_set_changelog' => 'Remplir le journal des changements', + 'pages_edit_enter_changelog_desc' => 'Entrez une brève description des changements effectués', + 'pages_edit_enter_changelog' => 'Entrez dans le journal des changements', + 'pages_save' => 'Enregistrez la page', + 'pages_title' => 'Titre de la page', + 'pages_name' => 'Nom de la page', + 'pages_md_editor' => 'Editeur', + 'pages_md_preview' => 'Prévisualisation', + 'pages_md_insert_image' => 'Insérer une image', + 'pages_md_insert_link' => 'Insérer un lien', + 'pages_not_in_chapter' => 'La page n\'est pas dans un chanpitre', + 'pages_move' => 'Déplacer la page', + 'pages_move_success' => 'Page déplacée à ":parentName"', + 'pages_permissions' => 'Permissions de la page', + 'pages_permissions_success' => 'Permissions de la page mises à jour', + 'pages_revisions' => 'Révisions de la page', + 'pages_revisions_named' => 'Révisions pour :pageName', + 'pages_revision_named' => 'Révision pour :pageName', + 'pages_revisions_created_by' => 'Créé par', + 'pages_revisions_date' => 'Date de révision', + 'pages_revisions_changelog' => 'Journal des changements', + 'pages_revisions_changes' => 'Changements', + 'pages_revisions_current' => 'Version courante', + 'pages_revisions_preview' => 'Prévisualisation', + 'pages_revisions_restore' => 'Restaurer', + 'pages_revisions_none' => 'Cette page n\'a aucune révision', + 'pages_export' => 'Exporter', + 'pages_export_html' => 'Fichiers web', + 'pages_export_pdf' => 'Fichier PDF', + 'pages_export_text' => 'Document texte', + 'pages_copy_link' => 'Copier le lien', + 'pages_permissions_active' => 'Permissions de page actives', + 'pages_initial_revision' => 'Publication initiale', + 'pages_initial_name' => 'Nouvelle page', + 'pages_editing_draft_notification' => 'Vous éditez actuellement un brouillon qui a été sauvé :timeDiff.', + 'pages_draft_edited_notification' => 'La page a été mise à jour depuis votre dernière visit. Vous devriez écarter ce brouillon.', + 'pages_draft_edit_active' => [ + 'start_a' => ':count utilisateurs ont commencé a éditer cette page', + 'start_b' => ':userName a commencé à éditer cette page', + 'time_a' => 'depuis la dernière sauvegarde', + 'time_b' => 'dans les :minCount dernières minutes', + 'message' => ':start :time. Attention a ne pas écraser les mises à jour de quelqu\'un d\'autre!', + ], + 'pages_draft_discarded' => 'Brouuillon écarté, la page est dans sa version actuelle.', + + /** + * Editor sidebar + */ + 'page_tags' => 'Mots-clés de la page', + 'tag' => 'Mot-clé', + 'tags' => 'Mots-clé', + 'tag_value' => 'Valeur du mot-clé (Optionnel)', + 'tags_explain' => "Ajouter des mot-clés pour catégoriser votre contenu.", + 'tags_add' => 'Ajouter un autre mot-clé', + 'attachments' => 'Fichiers joints', + 'attachments_explain' => 'Ajouter des fichiers ou des liens pour les afficher sur votre page. Ils seront affichés dans la barre latérale', + 'attachments_explain_instant_save' => 'Ces changements sont enregistrés immédiatement.', + 'attachments_items' => 'Fichiers joints', + 'attachments_upload' => 'Uploader un fichier', + 'attachments_link' => 'Attacher un lien', + 'attachments_set_link' => 'Définir un lien', + 'attachments_delete_confirm' => 'Cliquer une seconde fois sur supprimer pour valider la suppression.', + 'attachments_dropzone' => 'Glissez des fichiers ou cliquez ici pour attacher des fichiers', + 'attachments_no_files' => 'Aucun fichier ajouté', + 'attachments_explain_link' => 'Vous pouvez attacher un lien si vous ne souhaitez pas uploader un fichier.', + 'attachments_link_name' => 'Nom du lien', + 'attachment_link' => 'Lien de l\'attachement', + 'attachments_link_url' => 'Lien sur un fichier', + 'attachments_link_url_hint' => 'URL du site ou du fichier', + 'attach' => 'Attacher', + 'attachments_edit_file' => 'Modifier le fichier', + 'attachments_edit_file_name' => 'Nom du fichier', + 'attachments_edit_drop_upload' => 'Glissez un fichier ou cliquer pour mettre à jour le fichier', + 'attachments_order_updated' => 'Ordre des fichiers joints mis à jour', + 'attachments_updated_success' => 'Détails des fichiers joints mis à jour', + 'attachments_deleted' => 'Fichier joint supprimé', + 'attachments_file_uploaded' => 'Fichier ajouté avec succès', + 'attachments_file_updated' => 'Fichier mis à jour avec succès', + 'attachments_link_attached' => 'Lien attaché à la page avec succès', + + /** + * Profile View + */ + 'profile_user_for_x' => 'Utilisateur depuis :time', + 'profile_created_content' => 'Contenu créé', + 'profile_not_created_pages' => ':userName n\'a pas créé de pages', + 'profile_not_created_chapters' => ':userName n\'a pas créé de chapitres', + 'profile_not_created_books' => ':userName n\'a pas créé de livres', +]; diff --git a/resources/lang/fr/errors.php b/resources/lang/fr/errors.php new file mode 100644 index 000000000..72af89f7f --- /dev/null +++ b/resources/lang/fr/errors.php @@ -0,0 +1,70 @@ + 'Vous n\'avez pas les droits pour accéder à cette page.', + 'permissionJson' => 'Vous n\'avez pas les droits pour exécuter cette action.', + + // Auth + 'error_user_exists_different_creds' => 'Un utilisateur avec l\'adresse :email existe déjà.', + 'email_already_confirmed' => 'Cet e-mail a déjà été validé, vous pouvez vous connecter.', + 'email_confirmation_invalid' => 'Cette confirmation est invalide. Veuillez essayer de vous inscrire à nouveau.', + 'email_confirmation_expired' => 'Le jeton de confirmation est perimé. Un nouvel e-mail vous a été envoyé.', + 'ldap_fail_anonymous' => 'L\'accès LDAP anonyme n\'a pas abouti', + 'ldap_fail_authed' => 'L\'accès LDAP n\'a pas abouti avec cet utilisateur et ce mot de passe', + 'ldap_extension_not_installed' => 'L\'extention LDAP PHP n\'est pas installée', + 'ldap_cannot_connect' => 'Cannot connect to ldap server, Initial connection failed', + 'social_no_action_defined' => 'No action defined', + 'social_account_in_use' => 'Cet compte :socialAccount est déjà utilisé. Essayez de vous connecter via :socialAccount.', + 'social_account_email_in_use' => 'L\'email :email Est déjà utilisé. Si vous avez déjà un compte :socialAccount, vous pouvez le joindre à votre profil existant.', + 'social_account_existing' => 'Ce compte :socialAccount est déjà rattaché à votre profil.', + 'social_account_already_used_existing' => 'Ce compte :socialAccount est déjà utilisé par un autre utilisateur.', + 'social_account_not_used' => 'Ce compte :socialAccount n\'est lié à aucun utilisateur. ', + 'social_account_register_instructions' => 'Si vous n\'avez pas encore de compte, vous pouvez le lier avec l\'option :socialAccount.', + 'social_driver_not_found' => 'Social driver not found', + 'social_driver_not_configured' => 'Your :socialAccount social settings are not configured correctly.', + + // System + 'path_not_writable' => 'File path :filePath could not be uploaded to. Ensure it is writable to the server.', + 'cannot_get_image_from_url' => 'Impossible de récupérer l\'image depuis :url', + 'cannot_create_thumbs' => 'Le serveur ne peux pas créer de miniatures, vérifier que l\extensions GD PHP est installée.', + 'server_upload_limit' => 'La taille du fichier est trop grande.', + 'image_upload_error' => 'Une erreur est survenue pendant l\'envoi de l\'image', + + // Attachments + 'attachment_page_mismatch' => 'Page mismatch during attachment update', + + // Pages + 'page_draft_autosave_fail' => 'Le brouillon n\'a pas pu être sauvé. Vérifiez votre connexion internet', + + // Entities + 'entity_not_found' => 'Entité non trouvée', + 'book_not_found' => 'Livre non trouvé', + 'page_not_found' => 'Page non trouvée', + 'chapter_not_found' => 'Chapitre non trouvé', + 'selected_book_not_found' => 'Ce livre n\'a pas été trouvé', + 'selected_book_chapter_not_found' => 'Ce livre ou chapitre n\'a pas été trouvé', + 'guests_cannot_save_drafts' => 'Les invités ne peuvent pas sauver de brouillons', + + // Users + 'users_cannot_delete_only_admin' => 'Vous ne pouvez pas supprimer le dernier admin', + 'users_cannot_delete_guest' => 'Vous ne pouvez pas supprimer l\'utilisateur invité', + + // Roles + 'role_cannot_be_edited' => 'Ce rôle ne peut pas être modifié', + 'role_system_cannot_be_deleted' => 'Ceci est un rôle du système et on ne peut pas le supprimer', + 'role_registration_default_cannot_delete' => 'Ce rôle ne peut pas être supprimé tant qu\'il est le rôle par défaut', + + // Error pages + '404_page_not_found' => 'Page non trouvée', + 'sorry_page_not_found' => 'Désolé, cette page n\'a pas pu être trouvée.', + 'return_home' => 'Retour à l\'accueil', + 'error_occurred' => 'Une erreur est survenue', + 'app_down' => ':appName n\'est pas en service pour le moment', + 'back_soon' => 'Nous serons bientôt de retour.', +]; diff --git a/resources/lang/fr/pagination.php b/resources/lang/fr/pagination.php new file mode 100644 index 000000000..9f07a5f93 --- /dev/null +++ b/resources/lang/fr/pagination.php @@ -0,0 +1,19 @@ + '« Précédent', + 'next' => 'Suivant »', + +]; diff --git a/resources/lang/fr/passwords.php b/resources/lang/fr/passwords.php new file mode 100644 index 000000000..7be81da23 --- /dev/null +++ b/resources/lang/fr/passwords.php @@ -0,0 +1,22 @@ + 'Les mots de passe doivent faire au moins 6 caractères et correspondre à la confirmation.', + 'user' => "Nous n'avons pas trouvé d'utilisateur avec cette adresse.", + 'token' => 'Le jeton de réinitialisation est invalide.', + 'sent' => 'Nous vous avons envoyé un lien de réinitialisation de mot de passe!', + 'reset' => 'Votre mot de passe a été réinitialisé!', + +]; diff --git a/resources/lang/fr/settings.php b/resources/lang/fr/settings.php new file mode 100644 index 000000000..8a3756527 --- /dev/null +++ b/resources/lang/fr/settings.php @@ -0,0 +1,112 @@ + 'Préférences', + 'settings_save' => 'Enregistrer les préférences', + 'settings_save_success' => 'Préférences enregistrées', + + /** + * App settings + */ + + 'app_settings' => 'Préférences de l\'application', + 'app_name' => 'Nom de l\'application', + 'app_name_desc' => 'Ce nom est affiché dans l\'en-tête et les e-mails.', + 'app_name_header' => 'Afficher le nom dans l\'en-tête?', + 'app_public_viewing' => 'Accepter le visionnage public des pages?', + 'app_secure_images' => 'Activer l\'ajout d\'image sécurisé?', + 'app_secure_images_desc' => 'Pour des questions de performances, toutes les images sont publiques. Cette option ajoute une chaîne aléatoire difficile à deviner dans les URLs des images.', + 'app_editor' => 'Editeur des pages', + 'app_editor_desc' => 'Sélectionnez l\'éditeur qui sera utilisé pour modifier les pages.', + 'app_custom_html' => 'HTML personnalisé dans l\'en-tête', + 'app_custom_html_desc' => 'Le contenu inséré ici sera jouté en bas de la balise de toutes les pages. Vous pouvez l\'utiliser pour ajouter du CSS personnalisé ou un tracker analytique.', + 'app_logo' => 'Logo de l\'Application', + 'app_logo_desc' => 'Cette image doit faire 43px de hauteur.
Les images plus larges seront réduites.', + 'app_primary_color' => 'Couleur principale de l\'application', + 'app_primary_color_desc' => 'This should be a hex value.
Leave empty to reset to the default color.', + + /** + * Registration settings + */ + + 'reg_settings' => 'Préférence pour l\'inscription', + 'reg_allow' => 'Accepter l\'inscription?', + 'reg_default_role' => 'Rôle par défaut lors de l\'inscription', + 'reg_confirm_email' => 'Obliger la confirmation par e-mail?', + 'reg_confirm_email_desc' => 'Si la restriction de domaine est activée, la confirmation sera automatiquement obligatoire et cette valeur sera ignorée.', + 'reg_confirm_restrict_domain' => 'Restreindre l\'inscription à un domaine', + 'reg_confirm_restrict_domain_desc' => 'Entrez une liste de domaines acceptés lors de l\'inscription, séparés par une virgule. Les utilisateur recevront un e-mail de confirmation à cette adresse.
Les utilisateurs pourront changer leur adresse après inscription s\'ils le souhaitent.', + 'reg_confirm_restrict_domain_placeholder' => 'Aucune restriction en place', + + /** + * Role settings + */ + + 'roles' => 'Rôles', + 'role_user_roles' => 'Rôles des utilisateurs', + 'role_create' => 'Créer un nouveau rôle', + 'role_create_success' => 'Rôle créé avec succès', + 'role_delete' => 'Supprimer le rôle', + 'role_delete_confirm' => 'Ceci va supprimer le rôle \':roleName\'.', + 'role_delete_users_assigned' => 'Ce rôle a :userCount utilisateurs assignés. Vous pouvez choisir un rôle de remplacement pour ces utilisateurs.', + 'role_delete_no_migration' => "Ne pas assigner de nouveau rôle", + 'role_delete_sure' => 'Êtes vous sûr(e) de vouloir supprimer ce rôle?', + 'role_delete_success' => 'Le rôle a été supprimé avec succès', + 'role_edit' => 'Modifier le rôle', + 'role_details' => 'Détails du rôle', + 'role_name' => 'Nom du Rôle', + 'role_desc' => 'Courte description du rôle', + 'role_system' => 'Permissions système', + 'role_manage_users' => 'Gérer les utilisateurs', + 'role_manage_roles' => 'Gérer les rôles et permissions', + 'role_manage_entity_permissions' => 'Gérer les permissions sur les livres, chapitres et pages', + 'role_manage_own_entity_permissions' => 'Gérer les permissions de ses propres livres chapitres et pages', + 'role_manage_settings' => 'Gérer les préférences de l\'application', + 'role_asset' => 'Asset Permissions', + 'role_asset_desc' => 'These permissions control default access to the assets within the system. Permissions on Books, Chapters and Pages will override these permissions.', + 'role_all' => 'Tous', + 'role_own' => 'Propres', + 'role_controlled_by_asset' => 'Controlled by the asset they are uploaded to', + 'role_save' => 'Enregistrer le rôle', + 'role_update_success' => 'Rôle mis à jour avec succès', + 'role_users' => 'Utilisateurs ayant ce rôle', + 'role_users_none' => 'Aucun utilisateur avec ce rôle actuellement', + + /** + * Users + */ + + 'users' => 'Utilisateurs', + 'user_profile' => 'Profil d\'utilisateur', + 'users_add_new' => 'Ajouter un nouvel utilisateur', + 'users_search' => 'Chercher les utilisateurs', + 'users_role' => 'Rôles des utilisateurs', + 'users_external_auth_id' => 'Identifiant d\'authentification externe', + 'users_password_warning' => 'Remplissez ce fomulaire uniquement si vous souhaitez changer de mot de passe:', + 'users_system_public' => 'Cet utilisateur représente les invités visitant votre instance. Il est assigné automatiquement aux invités.', + 'users_delete' => 'Supprimer un utilisateur', + 'users_delete_named' => 'Supprimer l\'utilisateur :userName', + 'users_delete_warning' => 'Ceci va supprimer \':userName\' du système.', + 'users_delete_confirm' => 'Êtes-vous sûr(e) de vouloir supprimer cet utilisateur?', + 'users_delete_success' => 'Utilisateurs supprimés avec succès', + 'users_edit' => 'Modifier l\'utilisateur', + 'users_edit_profile' => 'Modifier le profil', + 'users_edit_success' => 'Utilisateur mis à jour avec succès', + 'users_avatar' => 'Avatar de l\'utilisateur', + 'users_avatar_desc' => 'Cette image doit être un carré d\'environ 256px.', + 'users_preferred_language' => 'Langue préférée', + 'users_social_accounts' => 'Comptes sociaux', + 'users_social_accounts_info' => 'Vous pouvez connecter des réseaux sociaux à votre compte pour vous connecter plus rapidement. Déconnecter un compte n\'enlèvera pas les accès autorisés précédemment sur votre compte de réseau social.', + 'users_social_connect' => 'Connecter le compte', + 'users_social_disconnect' => 'Déconnecter le compte', + 'users_social_connected' => 'Votre compte :socialAccount a élté ajouté avec succès.', + 'users_social_disconnected' => 'Votre compte :socialAccount a été déconnecté avec succès', + +]; diff --git a/resources/lang/fr/validation.php b/resources/lang/fr/validation.php new file mode 100644 index 000000000..9204f4e2d --- /dev/null +++ b/resources/lang/fr/validation.php @@ -0,0 +1,108 @@ + ':attribute doit être accepté.', + 'active_url' => ':attribute n\'est pas une URL valide.', + 'after' => ':attribute doit être supérieur à :date.', + 'alpha' => ':attribute ne doit contenir que des lettres.', + 'alpha_dash' => ':attribute doit contenir uniquement des lettres, chiffres et traits d\'union.', + 'alpha_num' => ':attribute doit contenir uniquement des chiffres et des lettres.', + 'array' => ':attribute doit être un tableau.', + 'before' => ':attribute doit être inférieur à :date.', + 'between' => [ + 'numeric' => ':attribute doit être compris entre :min et :max.', + 'file' => ':attribute doit être compris entre :min et :max kilobytes.', + 'string' => ':attribute doit être compris entre :min et :max caractères.', + 'array' => ':attribute doit être compris entre :min et :max éléments.', + ], + 'boolean' => ':attribute doit être vrai ou faux.', + 'confirmed' => ':attribute la confirmation n\'est pas valide.', + 'date' => ':attribute n\'est pas une date valide.', + 'date_format' => ':attribute ne correspond pas au format :format.', + 'different' => ':attribute et :other doivent être différents l\'un de l\'autre.', + 'digits' => ':attribute doit être de longueur :digits.', + 'digits_between' => ':attribute doit avoir une longueur entre :min et :max.', + 'email' => ':attribute doit être une adresse e-mail valide.', + 'filled' => ':attribute est un champ requis.', + 'exists' => 'L\'attribut :attribute est invalide.', + 'image' => ':attribute doit être une image.', + 'in' => 'L\'attribut :attribute est invalide.', + 'integer' => ':attribute doit être un chiffre entier.', + 'ip' => ':attribute doit être une adresse IP valide.', + 'max' => [ + 'numeric' => ':attribute ne doit pas excéder :max.', + 'file' => ':attribute ne doit pas excéder :max kilobytes.', + 'string' => ':attribute ne doit pas excéder :max caractères.', + 'array' => ':attribute ne doit pas contenir plus de :max éléments.', + ], + 'mimes' => ':attribute doit être un fichier de type :values.', + 'min' => [ + 'numeric' => ':attribute doit être au moins :min.', + 'file' => ':attribute doit faire au moins :min kilobytes.', + 'string' => ':attribute doit contenir au moins :min caractères.', + 'array' => ':attribute doit contenir au moins :min éléments.', + ], + 'not_in' => 'L\'attribut sélectionné :attribute est invalide.', + 'numeric' => ':attribute doit être un nombre.', + 'regex' => ':attribute a un format invalide.', + 'required' => ':attribute est un champ requis.', + 'required_if' => ':attribute est requis si :other est :value.', + 'required_with' => ':attribute est requis si :values est présent.', + 'required_with_all' => ':attribute est requis si :values est présent.', + 'required_without' => ':attribute est requis si:values n\'est pas présent.', + 'required_without_all' => ':attribute est requis si aucun des valeurs :values n\'est présente.', + 'same' => ':attribute et :other doivent être identiques.', + 'size' => [ + 'numeric' => ':attribute doit avoir la taille :size.', + 'file' => ':attribute doit peser :size kilobytes.', + 'string' => ':attribute doit contenir :size caractères.', + 'array' => ':attribute doit contenir :size éléments.', + ], + 'string' => ':attribute doit être une chaîne de caractères.', + 'timezone' => ':attribute doit être une zone valide.', + 'unique' => ':attribute est déjà utilisé.', + 'url' => ':attribute a un format invalide.', + + /* + |-------------------------------------------------------------------------- + | Custom Validation Language Lines + |-------------------------------------------------------------------------- + | + | Here you may specify custom validation messages for attributes using the + | convention "attribute.rule" to name the lines. This makes it quick to + | specify a specific custom language line for a given attribute rule. + | + */ + + 'custom' => [ + 'password-confirm' => [ + 'required_with' => 'La confirmation du mot de passe est requise', + ], + ], + + /* + |-------------------------------------------------------------------------- + | Custom Validation Attributes + |-------------------------------------------------------------------------- + | + | The following language lines are used to swap attribute place-holders + | with something more reader friendly such as E-Mail Address instead + | of "email". This simply helps us make messages a little cleaner. + | + */ + + 'attributes' => [], + +]; diff --git a/resources/lang/pt_BR/activities.php b/resources/lang/pt_BR/activities.php new file mode 100644 index 000000000..1f5bc3528 --- /dev/null +++ b/resources/lang/pt_BR/activities.php @@ -0,0 +1,40 @@ + 'página criada', + 'page_create_notification' => 'Página criada com sucesso', + 'page_update' => 'página atualizada', + 'page_update_notification' => 'Página atualizada com sucesso', + 'page_delete' => 'página excluída', + 'page_delete_notification' => 'Página excluída com sucesso', + 'page_restore' => 'página restaurada', + 'page_restore_notification' => 'Página restaurada com sucesso', + 'page_move' => 'página movida', + + // Chapters + 'chapter_create' => 'capítulo criado', + 'chapter_create_notification' => 'Capítulo criado com sucesso', + 'chapter_update' => 'capítulo atualizado', + 'chapter_update_notification' => 'capítulo atualizado com sucesso', + 'chapter_delete' => 'capítulo excluído', + 'chapter_delete_notification' => 'Capítulo excluído com sucesso', + 'chapter_move' => 'capitulo movido', + + // Books + 'book_create' => 'livro criado', + 'book_create_notification' => 'Livro criado com sucesso', + 'book_update' => 'livro atualizado', + 'book_update_notification' => 'Livro atualizado com sucesso', + 'book_delete' => 'livro excluído', + 'book_delete_notification' => 'Livro excluído com sucesso', + 'book_sort' => 'livro classificado', + 'book_sort_notification' => 'Livro reclassificado com sucesso', + +]; diff --git a/resources/lang/pt_BR/auth.php b/resources/lang/pt_BR/auth.php new file mode 100644 index 000000000..ec3b92def --- /dev/null +++ b/resources/lang/pt_BR/auth.php @@ -0,0 +1,74 @@ + 'As credenciais fornecidas não puderam ser validadas em nossos registros..', + 'throttle' => 'Muitas tentativas de login. Por favor, tente novamente em :seconds segundos.', + + /** + * Login & Register + */ + 'sign_up' => 'Registrar-se', + 'log_in' => 'Entrar', + 'logout' => 'Sair', + + 'name' => 'Nome', + 'username' => 'Nome de Usuário', + 'email' => 'E-mail', + 'password' => 'Senha', + 'password_confirm' => 'Confirmar Senha', + 'password_hint' => 'Senha deverá ser maior que 5 caracteres', + 'forgot_password' => 'Esqueceu a senha?', + 'remember_me' => 'Lembrar de mim', + 'ldap_email_hint' => 'Por favor, digite um e-mail para essa conta.', + 'create_account' => 'Criar conta', + 'social_login' => 'Login social', + 'social_registration' => 'Registro social', + 'social_registration_text' => 'Registre e entre usando outro serviço.', + + 'register_thanks' => 'Obrigado por efetuar o registro!', + 'register_confirm' => 'Por favor, verifique seu e-mail e clique no botão de confirmação para acessar :appName.', + 'registrations_disabled' => 'Registros estão temporariamente desabilitados', + 'registration_email_domain_invalid' => 'O domínio de e-mail usado não tem acesso permitido a essa aplicação', + 'register_success' => 'Obrigado por se registrar! Você agora encontra-se registrado e logado..', + + + /** + * Password Reset + */ + 'reset_password' => 'Resetar senha', + 'reset_password_send_instructions' => 'Digite seu e-mail abaixo e o sistema enviará uma mensagem com o link de reset de senha.', + 'reset_password_send_button' => 'Enviar o link de reset de senha', + 'reset_password_sent_success' => 'Um link de reset de senha foi enviado para :email.', + 'reset_password_success' => 'Sua senha foi resetada com sucesso.', + + 'email_reset_subject' => 'Resetar a senha de :appName', + 'email_reset_text' => 'Você recebeu esse e-mail pois recebemos uma solicitação de reset de senha para sua conta.', + 'email_reset_not_requested' => 'Caso não tenha sido você a solicitar o reset de senha, ignore esse e-mail.', + + + /** + * Email Confirmation + */ + 'email_confirm_subject' => 'Confirme seu e-mail para :appName', + 'email_confirm_greeting' => 'Obrigado por se registrar em :appName!', + 'email_confirm_text' => 'Por favor, confirme seu endereço de e-mail clicando no botão abaixo:', + 'email_confirm_action' => 'Confirmar E-mail', + 'email_confirm_send_error' => 'E-mail de confirmação é requerido, mas o sistema não pôde enviar a mensagem. Por favor, entre em contato com o admin para se certificar que o serviço de envio de e-mails está corretamente configurado.', + 'email_confirm_success' => 'Seu e-mail foi confirmado!', + 'email_confirm_resent' => 'E-mail de confirmação reenviado. Por favor, cheque sua caixa postal.', + + 'email_not_confirmed' => 'Endereço de e-mail não foi confirmado', + 'email_not_confirmed_text' => 'Seu endereço de e-mail ainda não foi confirmado.', + 'email_not_confirmed_click_link' => 'Por favor, clique no link no e-mail que foi enviado após o registro.', + 'email_not_confirmed_resend' => 'Caso não encontre o e-mail você poderá reenviar a confirmação usando o formulário abaixo.', + 'email_not_confirmed_resend_button' => 'Reenviar o e-mail de confirmação', +]; \ No newline at end of file diff --git a/resources/lang/pt_BR/common.php b/resources/lang/pt_BR/common.php new file mode 100644 index 000000000..820ba219c --- /dev/null +++ b/resources/lang/pt_BR/common.php @@ -0,0 +1,58 @@ + 'Cancelar', + 'confirm' => 'Confirmar', + 'back' => 'Voltar', + 'save' => 'Salvar', + 'continue' => 'Continuar', + 'select' => 'Selecionar', + + /** + * Form Labels + */ + 'name' => 'Nome', + 'description' => 'Descrição', + 'role' => 'Regra', + + /** + * Actions + */ + 'actions' => 'Ações', + 'view' => 'Visualizar', + 'create' => 'Criar', + 'update' => 'Atualizar', + 'edit' => 'Editar', + 'sort' => 'Ordenar', + 'move' => 'Mover', + 'delete' => 'Excluir', + 'search' => 'Pesquisar', + 'search_clear' => 'Limpar Pesquisa', + 'reset' => 'Resetar', + 'remove' => 'Remover', + + + /** + * Misc + */ + 'deleted_user' => 'Usuário excluído', + 'no_activity' => 'Nenhuma atividade a mostrar', + 'no_items' => 'Nenhum item disponível', + 'back_to_top' => 'Voltar ao topo', + 'toggle_details' => 'Alternar Detalhes', + + /** + * Header + */ + 'view_profile' => 'Visualizar Perfil', + 'edit_profile' => 'Editar Perfil', + + /** + * Email Content + */ + 'email_action_help' => 'Se você estiver tendo problemas ao clicar o botão ":actionText", copie e cole a URL abaixo no seu navegador:', + 'email_rights' => 'Todos os direitos reservados', +]; \ No newline at end of file diff --git a/resources/lang/pt_BR/components.php b/resources/lang/pt_BR/components.php new file mode 100644 index 000000000..5c1ec4241 --- /dev/null +++ b/resources/lang/pt_BR/components.php @@ -0,0 +1,24 @@ + 'Selecionar imagem', + 'image_all' => 'Todos', + 'image_all_title' => 'Visualizar todas as imagens', + 'image_book_title' => 'Visualizar imagens relacionadas a esse livro', + 'image_page_title' => 'visualizar imagens relacionadas a essa página', + 'image_search_hint' => 'Pesquisar imagem por nome', + 'image_uploaded' => 'Carregado :uploadedDate', + 'image_load_more' => 'Carregar Mais', + 'image_image_name' => 'Nome da Imagem', + 'image_delete_confirm' => 'Essa imagem é usada nas páginas abaixo. Clique em Excluir novamente para confirmar que você deseja mesmo eliminar a imagem.', + 'image_select_image' => 'Selecionar Imagem', + 'image_dropzone' => 'Arraste imagens ou clique aqui para fazer upload', + 'images_deleted' => 'Imagens excluídas', + 'image_preview' => 'Virtualização de Imagem', + 'image_upload_success' => 'Upload de imagem efetuado com sucesso', + 'image_update_success' => 'Upload de detalhes da imagem efetuado com sucesso', + 'image_delete_success' => 'Imagem excluída com sucesso' +]; \ No newline at end of file diff --git a/resources/lang/pt_BR/entities.php b/resources/lang/pt_BR/entities.php new file mode 100644 index 000000000..a6e670353 --- /dev/null +++ b/resources/lang/pt_BR/entities.php @@ -0,0 +1,226 @@ + 'Recentemente criado', + 'recently_created_pages' => 'Páginas recentemente criadas', + 'recently_updated_pages' => 'Páginas recentemente atualizadas', + 'recently_created_chapters' => 'Capítulos recentemente criados', + 'recently_created_books' => 'Livros recentemente criados', + 'recently_update' => 'Recentemente atualizado', + 'recently_viewed' => 'Recentemente visualizado', + 'recent_activity' => 'Atividade recente', + 'create_now' => 'Criar um agora', + 'revisions' => 'Revisões', + 'meta_created' => 'Criado em :timeLength', + 'meta_created_name' => 'Criado em :timeLength por :user', + 'meta_updated' => 'Atualizado em :timeLength', + 'meta_updated_name' => 'Atualizado em :timeLength por :user', + 'x_pages' => ':count Páginas', + 'entity_select' => 'Seleção de Entidade', + 'images' => 'Imagens', + 'my_recent_drafts' => 'Meus rascunhos recentes', + 'my_recently_viewed' => 'Meus itens recentemente visto', + 'no_pages_viewed' => 'Você não visualizou nenhuma página', + 'no_pages_recently_created' => 'Nenhuma página recentemente criada', + 'no_pages_recently_updated' => 'Nenhuma página recentemente atualizada', + + /** + * Permissions and restrictions + */ + 'permissions' => 'Permissões', + 'permissions_intro' => 'Uma vez habilitado, as permissões terão prioridade sobre outro conjunto de permissões.', + 'permissions_enable' => 'Habilitar Permissões Customizadas', + 'permissions_save' => 'Salvar Permissões', + + /** + * Search + */ + 'search_results' => 'Resultado(s) da Pesquisa', + 'search_results_page' => 'Resultado(s) de Pesquisa de Página', + 'search_results_chapter' => 'Resultado(s) de Pesquisa de Capítulo', + 'search_results_book' => 'Resultado(s) de Pesquisa de Livro', + 'search_clear' => 'Limpar Pesquisa', + 'search_view_pages' => 'Visualizar todas as páginas correspondentes', + 'search_view_chapters' => 'Visualizar todos os capítulos correspondentes', + 'search_view_books' => 'Visualizar todos os livros correspondentes', + 'search_no_pages' => 'Nenhuma página corresponde à pesquisa', + 'search_for_term' => 'Pesquisar por :term', + 'search_page_for_term' => 'Pesquisar Página por :term', + 'search_chapter_for_term' => 'Pesquisar Capítulo por :term', + 'search_book_for_term' => 'Pesquisar Livros por :term', + + /** + * Books + */ + 'book' => 'Livro', + 'books' => 'Livros', + 'books_empty' => 'Nenhum livro foi criado', + 'books_popular' => 'Livros populares', + 'books_recent' => 'Livros recentes', + 'books_popular_empty' => 'Os livros mais populares aparecerão aqui.', + 'books_create' => 'Criar novo Livro', + 'books_delete' => 'Excluir Livro', + 'books_delete_named' => 'Excluir Livro :bookName', + 'books_delete_explain' => 'A ação vai excluír o livro com o nome \':bookName\'. Todas as páginas e capítulos serão removidos.', + 'books_delete_confirmation' => 'Você tem certeza que quer excluír o Livro?', + 'books_edit' => 'Editar Livro', + 'books_edit_named' => 'Editar Livro :bookName', + 'books_form_book_name' => 'Nome do Livro', + 'books_save' => 'Salvar Livro', + 'books_permissions' => 'Permissões do Livro', + 'books_permissions_updated' => 'Permissões do Livro Atualizadas', + 'books_empty_contents' => 'Nenhuma página ou capítulo criado para esse livro.', + 'books_empty_create_page' => 'Criar uma nova página', + 'books_empty_or' => 'ou', + 'books_empty_sort_current_book' => 'Ordenar o livro atual', + 'books_empty_add_chapter' => 'Adicionar um capítulo', + 'books_permissions_active' => 'Permissões do Livro ativadas', + 'books_search_this' => 'Pesquisar esse livro', + 'books_navigation' => 'Navegação do Livro', + 'books_sort' => 'Ordenar conteúdos do Livro', + 'books_sort_named' => 'Ordenar Livro :bookName', + 'books_sort_show_other' => 'Mostrar outros livros', + 'books_sort_save' => 'Salvar nova ordenação', + + /** + * Chapters + */ + 'chapter' => 'Capitulo', + 'chapters' => 'Capítulos', + 'chapters_popular' => 'Capítulos Populares', + 'chapters_new' => 'Novo Capítulo', + 'chapters_create' => 'Criar novo Capítulo', + 'chapters_delete' => 'Excluír Capítulo', + 'chapters_delete_named' => 'Excluir Capítulo :chapterName', + 'chapters_delete_explain' => 'A ação vai excluír o capítulo de nome \':chapterName\'. Todas as páginas do capítulo serão removidas + e adicionadas diretamente ao livro pai.', + 'chapters_delete_confirm' => 'Tem certeza que deseja excluír o capitulo?', + 'chapters_edit' => 'Editar Capítulo', + 'chapters_edit_named' => 'Editar capitulo :chapterName', + 'chapters_save' => 'Salvar Capítulo', + 'chapters_move' => 'Mover Capítulo', + 'chapters_move_named' => 'Mover Capítulo :chapterName', + 'chapter_move_success' => 'Capítulo movido para :bookName', + 'chapters_permissions' => 'Permissões do Capítulo', + 'chapters_empty' => 'Nenhuma página existente nesse capítulo.', + 'chapters_permissions_active' => 'Permissões de Capítulo ativadas', + 'chapters_permissions_success' => 'Permissões de Capítulo atualizadas', + + /** + * Pages + */ + 'page' => 'Página', + 'pages' => 'Páginas', + 'pages_popular' => 'Páginas Popular', + 'pages_new' => 'Nova Página', + 'pages_attachments' => 'Anexos', + 'pages_navigation' => 'Página de Navegação', + 'pages_delete' => 'Excluír Página', + 'pages_delete_named' => 'Excluír Página :pageName', + 'pages_delete_draft_named' => 'Excluir rascunho de Página de nome :pageName', + 'pages_delete_draft' => 'Excluir rascunho de Página', + 'pages_delete_success' => 'Página excluída', + 'pages_delete_draft_success' => 'Página de rascunho excluída', + 'pages_delete_confirm' => 'Tem certeza que deseja excluir a página?', + 'pages_delete_draft_confirm' => 'Tem certeza que deseja excluir o rascunho de página?', + 'pages_editing_named' => 'Editando a Página :pageName', + 'pages_edit_toggle_header' => 'Alternar cabeçalho', + 'pages_edit_save_draft' => 'Salvar Rascunho', + 'pages_edit_draft' => 'Editar rascunho de Página', + 'pages_editing_draft' => 'Editando Rascunho', + 'pages_editing_page' => 'Editando Página', + 'pages_edit_draft_save_at' => 'Rascunho salvo em ', + 'pages_edit_delete_draft' => 'Excluir rascunho', + 'pages_edit_discard_draft' => 'Descartar rascunho', + 'pages_edit_set_changelog' => 'Definir Changelog', + 'pages_edit_enter_changelog_desc' => 'Digite uma breve descrição das mudanças efetuadas por você', + 'pages_edit_enter_changelog' => 'Entrar no Changelog', + 'pages_save' => 'Salvar Página', + 'pages_title' => 'Título de Página', + 'pages_name' => 'Nome da Página', + 'pages_md_editor' => 'Editor', + 'pages_md_preview' => 'Preview', + 'pages_md_insert_image' => 'Inserir Imagem', + 'pages_md_insert_link' => 'Inserir Link para Entidade', + 'pages_not_in_chapter' => 'Página não está dentro de um Capítulo', + 'pages_move' => 'Mover Página', + 'pages_move_success' => 'Pagina movida para ":parentName"', + 'pages_permissions' => 'Permissões de Página', + 'pages_permissions_success' => 'Permissões de Página atualizadas', + 'pages_revisions' => 'Revisões de Página', + 'pages_revisions_named' => 'Revisões de Página para :pageName', + 'pages_revision_named' => 'Revisão de Página para :pageName', + 'pages_revisions_created_by' => 'Criado por', + 'pages_revisions_date' => 'Data da Revisão', + 'pages_revisions_changelog' => 'Changelog', + 'pages_revisions_changes' => 'Mudanças', + 'pages_revisions_current' => 'Versão atual', + 'pages_revisions_preview' => 'Preview', + 'pages_revisions_restore' => 'Restaurar', + 'pages_revisions_none' => 'Essa página não tem revisões', + 'pages_export' => 'Exportar', + 'pages_export_html' => 'Arquivo Web Contained', + 'pages_export_pdf' => 'Arquivo PDF', + 'pages_export_text' => 'Arquivo Texto', + 'pages_copy_link' => 'Copia Link', + 'pages_permissions_active' => 'Permissões de Página Ativas', + 'pages_initial_revision' => 'Publicação Inicial', + 'pages_initial_name' => 'Nova Página', + 'pages_editing_draft_notification' => 'Você está atualmente editando um rascunho que foi salvo da última vez em :timeDiff.', + 'pages_draft_edited_notification' => 'Essa página foi atualizada desde então. É recomendado que você descarte esse rascunho.', + 'pages_draft_edit_active' => [ + 'start_a' => ':count usuários que iniciaram edição dessa página', + 'start_b' => ':userName iniciou a edição dessa página', + 'time_a' => 'desde que a página foi atualizada pela última vez', + 'time_b' => 'nos últimos :minCount minutos', + 'message' => ':start :time. Tome cuidado para não sobrescrever atualizações de outras pessoas!', + ], + 'pages_draft_discarded' => 'Rascunho descartado. O editor foi atualizado com a página atualizada', + + /** + * Editor sidebar + */ + 'page_tags' => 'Tags de Página', + 'tag' => 'Tag', + 'tags' => '', + 'tag_value' => 'Valor da Tag (Opcional)', + 'tags_explain' => "Adicione algumas tags para melhor categorizar seu conteúdo. \n Você pode atrelar um valor para uma tag para uma organização mais consistente.", + 'tags_add' => 'Adicionar outra tag', + 'attachments' => 'Anexos', + 'attachments_explain' => 'Faça o Upload de alguns arquivos ou anexo algum link para ser mostrado na sua página. Eles estarão visíveis na barra lateral à direita da página.', + 'attachments_explain_instant_save' => 'Mudanças são salvas instantaneamente.', + 'attachments_items' => 'Itens Anexados', + 'attachments_upload' => 'Upload de arquivos', + 'attachments_link' => 'Links Anexados', + 'attachments_set_link' => 'Definir Link', + 'attachments_delete_confirm' => 'Clique novamente em Excluir para confirmar a exclusão desse anexo.', + 'attachments_dropzone' => 'Arraste arquivos para cá ou clique para anexar arquivos', + 'attachments_no_files' => 'Nenhum arquivo foi enviado', + 'attachments_explain_link' => 'Você pode anexar um link se preferir não fazer o upload do arquivo. O link poderá ser para uma outra página ou link para um arquivo na nuvem.', + 'attachments_link_name' => 'Nome do Link', + 'attachment_link' => 'Link para o Anexo', + 'attachments_link_url' => 'Link para o Arquivo', + 'attachments_link_url_hint' => 'URL do site ou arquivo', + 'attach' => 'Anexar', + 'attachments_edit_file' => 'Editar Arquivo', + 'attachments_edit_file_name' => 'Nome do Arquivo', + 'attachments_edit_drop_upload' => 'Arraste arquivos para cá ou clique para anexar arquivos e sobrescreve-lo', + 'attachments_order_updated' => 'Ordem dos anexos atualizada', + 'attachments_updated_success' => 'Detalhes dos anexos atualizados', + 'attachments_deleted' => 'Anexo excluído', + 'attachments_file_uploaded' => 'Upload de arquivo efetuado com sucesso', + 'attachments_file_updated' => 'Arquivo atualizado com sucesso', + 'attachments_link_attached' => 'Link anexado com sucesso à página', + + /** + * Profile View + */ + 'profile_user_for_x' => 'Usuário por :time', + 'profile_created_content' => 'Conteúdo Criado', + 'profile_not_created_pages' => ':userName não criou páginas', + 'profile_not_created_chapters' => ':userName não criou capítulos', + 'profile_not_created_books' => ':userName não criou livros', +]; \ No newline at end of file diff --git a/resources/lang/pt_BR/errors.php b/resources/lang/pt_BR/errors.php new file mode 100644 index 000000000..91b85e3ef --- /dev/null +++ b/resources/lang/pt_BR/errors.php @@ -0,0 +1,70 @@ + 'Você não tem permissões para acessar a página requerida.', + 'permissionJson' => 'Você não tem permissão para realizar a ação requerida.', + + // Auth + 'error_user_exists_different_creds' => 'Um usuário com o e-mail :email já existe mas com credenciais diferentes.', + 'email_already_confirmed' => 'E-mail já foi confirmado. Tente efetuar o login.', + 'email_confirmation_invalid' => 'Esse token de confirmação não é válido ou já foi utilizado. Por favor, tente efetuar o registro novamente.', + 'email_confirmation_expired' => 'O token de confirmação já expirou. Um novo e-mail foi enviado.', + 'ldap_fail_anonymous' => 'O acesso LDAP falhou ao tentar usar o anonymous bind', + 'ldap_fail_authed' => 'O acesso LDAPfalou ao tentar os detalhes do dn e senha fornecidos', + 'ldap_extension_not_installed' => 'As extensões LDAP PHP não estão instaladas', + 'ldap_cannot_connect' => 'Não foi possível conectar ao servidor LDAP. Conexão inicial falhou', + 'social_no_action_defined' => 'Nenhuma ação definida', + 'social_account_in_use' => 'Essa conta :socialAccount já está em uso. Por favor, tente se logar usando a opção :socialAccount', + 'social_account_email_in_use' => 'O e-mail :email já está e muso. Se você já tem uma conta você poderá se conectar a conta :socialAccount a partir das configurações de seu perfil.', + 'social_account_existing' => 'Essa conta :socialAccount já está atrelada a esse perfil.', + 'social_account_already_used_existing' => 'Essa conta :socialAccount já está sendo usada por outro usuário.', + 'social_account_not_used' => 'Essa conta :socialAccount não está atrelada a nenhum usuário. Por favor, faça o link da conta com suas configurações de perfil. ', + 'social_account_register_instructions' => 'Se você não tem uma conta, você poderá fazer o registro usando a opção :socialAccount', + 'social_driver_not_found' => 'Social driver não encontrado', + 'social_driver_not_configured' => 'Seus parâmetros socials de :socialAccount não estão configurados corretamente.', + + // System + 'path_not_writable' => 'O caminho de destino (:filePath) de upload de arquivo não possui permissão de escrita. Certifique-se que ele possui direitos de escrita no servidor.', + 'cannot_get_image_from_url' => 'Não foi possivel capturar a imagem a partir de :url', + 'cannot_create_thumbs' => 'O servidor não pôde criar as miniaturas de imagem. Por favor, verifique se a extensão GD PHP está instalada.', + 'server_upload_limit' => 'O servidor não permite o upload de arquivos com esse tamanho. Por favor, tente fazer o upload de arquivos de menor tamanho.', + 'image_upload_error' => 'Um erro aconteceu enquanto o servidor tentava efetuar o upload da imagem', + + // Attachments + 'attachment_page_mismatch' => 'Erro de \'Page mismatch\' durante a atualização do anexo', + + // Pages + 'page_draft_autosave_fail' => 'Falou ao tentar salvar o rascunho. Certifique-se que a conexão de internet está funcional antes de tentar salvar essa página', + + // Entities + 'entity_not_found' => 'Entidade não encontrada', + 'book_not_found' => 'Livro não encontrado', + 'page_not_found' => 'Página não encontrada', + 'chapter_not_found' => 'Capítulo não encontrado', + 'selected_book_not_found' => 'O livro selecionado não foi encontrado', + 'selected_book_chapter_not_found' => 'O Livro selecionado ou Capítulo não foi encontrado', + 'guests_cannot_save_drafts' => 'Convidados não podem salvar rascunhos', + + // Users + 'users_cannot_delete_only_admin' => 'Você não pode excluir o conteúdo, apenas o admin.', + 'users_cannot_delete_guest' => 'Você não pode excluir o usuário convidado', + + // Roles + 'role_cannot_be_edited' => 'Esse perfil não poed ser editado', + 'role_system_cannot_be_deleted' => 'Esse perfil é um perfil de sistema e não pode ser excluído', + 'role_registration_default_cannot_delete' => 'Esse perfil não poderá se excluído enquando estiver registrado como o perfil padrão', + + // Error pages + '404_page_not_found' => 'Página não encontrada', + 'sorry_page_not_found' => 'Desculpe, a página que você está procurando não pôde ser encontrada.', + 'return_home' => 'Retornar à página principal', + 'error_occurred' => 'Um erro ocorreu', + 'app_down' => ':appName está fora do ar no momento', + 'back_soon' => 'Voltaremos em seguida.', +]; \ No newline at end of file diff --git a/resources/lang/pt_BR/pagination.php b/resources/lang/pt_BR/pagination.php new file mode 100644 index 000000000..6a32f34ac --- /dev/null +++ b/resources/lang/pt_BR/pagination.php @@ -0,0 +1,19 @@ + '« Anterior', + 'next' => 'Próximo »', + +]; diff --git a/resources/lang/pt_BR/passwords.php b/resources/lang/pt_BR/passwords.php new file mode 100644 index 000000000..f75c24ea5 --- /dev/null +++ b/resources/lang/pt_BR/passwords.php @@ -0,0 +1,22 @@ + 'Senhas devem ter ao menos 6 caraceres e combinar com os atributos mínimos para a senha.', + 'user' => "Não pudemos encontrar um usuário com o e-mail fornecido.", + 'token' => 'O token de reset de senha é inválido.', + 'sent' => 'Enviamos para seu e-mail o link de reset de senha!', + 'reset' => 'Sua senha foi resetada com sucesso!', + +]; diff --git a/resources/lang/pt_BR/settings.php b/resources/lang/pt_BR/settings.php new file mode 100644 index 000000000..b8d062b5f --- /dev/null +++ b/resources/lang/pt_BR/settings.php @@ -0,0 +1,140 @@ + 'Configurações', + 'settings_save' => 'Salvar Configurações', + 'settings_save_success' => 'Configurações Salvas', + + /** + * App settings + */ + + 'app_settings' => 'Configurações do App', + 'app_name' => 'Nome da Aplicação', + 'app_name_desc' => 'Esse nome será mostrado no cabeçalho e em e-mails.', + 'app_name_header' => 'Mostrar o nome da Aplicação no cabeçalho?', + 'app_public_viewing' => 'Permitir visualização pública?', + 'app_secure_images' => 'Permitir upload de imagens com maior segurança?', + 'app_secure_images_desc' => 'Por questões de performance, todas as imagens são públicas. Essa opção adiciona uma string randômica na frente da imagem. Certifique-se de que os índices do diretórios permitem o acesso fácil.', + 'app_editor' => 'Editor de Página', + 'app_editor_desc' => 'Selecione qual editor a ser usado pelos usuários para editar páginas.', + 'app_custom_html' => 'Conteúdo para tag HTML HEAD customizado', + 'app_custom_html_desc' => 'Quaisquer conteúdos aqui inseridos serão inseridos no final da seção do HTML de cada página. Essa é uma maneira útil de sobrescrever estilos e adicionar códigos de análise de site.', + 'app_logo' => 'Logo da Aplicação', + 'app_logo_desc' => 'A imagem deve ter 43px de altura.
Imagens mais largas devem ser reduzidas.', + 'app_primary_color' => 'Cor primária da Aplicação', + 'app_primary_color_desc' => 'Esse valor deverá ser Hexadecimal.
Deixe em branco para que o Bookstack assuma a cor padrão.', + + /** + * Registration settings + */ + + 'reg_settings' => 'Parâmetros de Registro', + 'reg_allow' => 'Permitir Registro?', + 'reg_default_role' => 'Perfil padrão para usuários após o registro', + 'reg_confirm_email' => 'Requerer confirmação por e-mail?', + 'reg_confirm_email_desc' => 'Se restrições de domínio são usadas a confirmação por e-mail será requerida e o valor abaixo será ignorado.', + 'reg_confirm_restrict_domain' => 'Restringir registro ao domínio', + 'reg_confirm_restrict_domain_desc' => 'Entre com uma lista de domínios de e-mails separados por vírgula para os quais você deseja restringir os registros. Será enviado um e-mail de confirmação para o usuário validar o e-mail antes de ser permitido interação com a aplicação.
Note que os usuários serão capazes de alterar o e-mail cadastrado após o sucesso na confirmação do registro.', + 'reg_confirm_restrict_domain_placeholder' => 'Nenhuma restrição configurada', + + /** + * Role settings + */ + + 'roles' => 'Perfis', + 'role_user_roles' => 'Perfis de Usuário', + 'role_create' => 'Criar novo Perfil', + 'role_create_success' => 'Perfil criado com sucesso', + 'role_delete' => 'Excluir Perfil', + 'role_delete_confirm' => 'A ação vai excluír o Perfil de nome \':roleName\'.', + 'role_delete_users_assigned' => 'Esse Perfil tem :userCount usuários assinalados a ele. Se quiser migrar usuários desse Perfil para outro, selecione um novo Perfil.', + 'role_delete_no_migration' => "Não migre os usuários", + 'role_delete_sure' => 'Tem certeza que deseja excluir esse Perfil?', + 'role_delete_success' => 'Perfil excluído com sucesso', + 'role_edit' => 'Editar Perfil', + 'role_details' => 'Detalhes do Perfil', + 'role_name' => 'Nome do Perfil', + 'role_desc' => 'Descrição Curta do Perfil', + 'role_system' => 'Permissões do Sistema', + 'role_manage_users' => 'Gerenciar Usuários', + 'role_manage_roles' => 'Gerenciar Perfis & Permissões de Perfis', + 'role_manage_entity_permissions' => 'Gerenciar todos os livros, capítulos e permissões de páginas', + 'role_manage_own_entity_permissions' => 'Gerenciar permissões de seu próprio livro, capítulo e paginas', + 'role_manage_settings' => 'Gerenciar configurações de app', + 'role_asset' => 'Permissões de Ativos', + 'role_asset_desc' => 'Essas permissões controlam o acesso padrão para os ativos dentro do sistema. Permissões em Livros, Capítulos e Páginas serão sobrescritas por essas permissões.', + 'role_all' => 'Todos', + 'role_own' => 'Próprio', + 'role_controlled_by_asset' => 'Controlado pelos ativos que você fez upload', + 'role_save' => 'Salvar Perfil', + 'role_update_success' => 'Perfil atualizado com sucesso', + 'role_users' => 'Usuários neste Perfil', + 'role_users_none' => 'Nenhum usuário está atualmente atrelado a esse Perfil', + + /** + * Users + */ + + 'users' => 'Usuários', + 'user_profile' => 'Perfil de Usuário', + 'users_add_new' => 'Adicionar Novo Usuário', + 'users_search' => 'Pesquisar Usuários', + 'users_role' => 'Perfis de Usuário', + 'users_external_auth_id' => 'ID de Autenticação Externa', + 'users_password_warning' => 'Preencha os dados abaixo caso queira modificar a sua senha:', + 'users_system_public' => 'Esse usuário representa quaisquer convidados que visitam o aplicativo. Ele não pode ser usado para login.', + 'users_delete' => 'Excluir Usuário', + 'users_delete_named' => 'Excluir :userName', + 'users_delete_warning' => 'A ação vai excluir completamente o usuário de nome \':userName\' do sistema.', + 'users_delete_confirm' => 'Tem certeza que deseja excluir esse usuário?', + 'users_delete_success' => 'Usuários excluídos com sucesso', + 'users_edit' => 'Editar usuário', + 'users_edit_profile' => 'Editar Perfil', + 'users_edit_success' => 'Usuário atualizado com sucesso', + 'users_avatar' => 'Imagem de Usuário', + 'users_avatar_desc' => 'Essa imagem deve ser um quadrado com aproximadamente 256px de altura e largura.', + 'users_social_accounts' => 'Contas Sociais', + 'users_social_accounts_info' => 'Aqui você pode conectar outras contas para acesso mais rápido. Desconectar uma conta não retira a possibilidade de acesso usando-a. Para revogar o acesso ao perfil através da conta social, você deverá fazê-lo na sua conta social.', + 'users_social_connect' => 'Contas conectadas', + 'users_social_disconnect' => 'Desconectar Conta', + 'users_social_connected' => 'Conta :socialAccount foi conectada com sucesso ao seu perfil.', + 'users_social_disconnected' => 'Conta :socialAccount foi desconectada com sucesso de seu perfil.', +]; + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/resources/lang/pt_BR/validation.php b/resources/lang/pt_BR/validation.php new file mode 100644 index 000000000..451dbe99c --- /dev/null +++ b/resources/lang/pt_BR/validation.php @@ -0,0 +1,108 @@ + 'O :attribute deve ser aceito.', + 'active_url' => 'O :attribute não é uma URL válida.', + 'after' => 'O :attribute deve ser uma data posterior à data :date.', + 'alpha' => 'O :attribute deve conter apenas letras.', + 'alpha_dash' => 'O :attribute deve conter apenas letras, números e traços.', + 'alpha_num' => 'O :attribute deve conter apenas letras e números.', + 'array' => 'O :attribute deve ser uma array.', + 'before' => 'O :attribute deve ser uma data anterior à data :date.', + 'between' => [ + 'numeric' => 'O :attribute deve ter tamanho entre :min e :max.', + 'file' => 'O :attribute deve ter entre :min e :max kilobytes.', + 'string' => 'O :attribute deve ter entre :min e :max caracteres.', + 'array' => 'O :attribute deve ter entre :min e :max itens.', + ], + 'boolean' => 'O campo :attribute deve ser verdadeiro ou falso.', + 'confirmed' => 'O campo :attribute de confirmação não é igual.', + 'date' => 'O campo :attribute não está em um formato de data válido.', + 'date_format' => 'O campo :attribute não tem a formatação :format.', + 'different' => 'O campo :attribute e o campo :other devem ser diferentes.', + 'digits' => 'O campo :attribute deve ter :digits dígitos.', + 'digits_between' => 'O campo :attribute deve ter entre :min e :max dígitos.', + 'email' => 'O campo :attribute deve ser um e-mail válido.', + 'filled' => 'O campo :attribute é requerido.', + 'exists' => 'O atributo :attribute selecionado não é válido.', + 'image' => 'O campo :attribute deve ser uma imagem.', + 'in' => 'The selected :attribute is invalid.', + 'integer' => 'O campo :attribute deve ser um número inteiro.', + 'ip' => 'O campo :attribute deve ser um IP válido.', + 'max' => [ + 'numeric' => 'O valor para o campo :attribute não deve ser maior que :max.', + 'file' => 'O valor para o campo :attribute não deve ter tamanho maior que :max kilobytes.', + 'string' => 'O valor para o campo :attribute não deve ter mais que :max caracteres.', + 'array' => 'O valor para o campo :attribute não deve ter mais que :max itens.', + ], + 'mimes' => 'O :attribute deve ser do tipo type: :values.', + 'min' => [ + 'numeric' => 'O valor para o campo :attribute não deve ser menor que :min.', + 'file' => 'O valor para o campo :attribute não deve ter tamanho menor que :min kilobytes.', + 'string' => 'O valor para o campo :attribute não deve ter menos que :min caracteres.', + 'array' => 'O valor para o campo :attribute não deve ter menos que :min itens.', + ], + 'not_in' => 'O campo selecionado :attribute é inválido.', + 'numeric' => 'O campo :attribute deve ser um número.', + 'regex' => 'O formato do campo :attribute é inválido.', + 'required' => 'O campo :attribute é requerido.', + 'required_if' => 'O campo :attribute é requerido quando o campo :other tem valor :value.', + 'required_with' => 'O campo :attribute é requerido quando os valores :values estiverem presentes.', + 'required_with_all' => 'O campo :attribute é requerido quando os valores :values estiverem presentes.', + 'required_without' => 'O campo :attribute é requerido quando os valores :values não estiverem presentes.', + 'required_without_all' => 'O campo :attribute é requerido quando nenhum dos valores :values estiverem presentes.', + 'same' => 'O campo :attribute e o campo :other devem ser iguais.', + 'size' => [ + 'numeric' => 'O tamanho do campo :attribute deve ser :size.', + 'file' => 'O tamanho do arquivo :attribute deve ser de :size kilobytes.', + 'string' => 'O tamanho do campo :attribute deve ser de :size caracteres.', + 'array' => 'O campo :attribute deve conter :size itens.', + ], + 'string' => 'O campo :attribute deve ser uma string.', + 'timezone' => 'O campo :attribute deve conter uma timezone válida.', + 'unique' => 'Já existe um campo/dado de nome :attribute.', + 'url' => 'O formato da URL :attribute é inválido.', + + /* + |-------------------------------------------------------------------------- + | Custom Validation Language Lines + |-------------------------------------------------------------------------- + | + | Here you may specify custom validation messages for attributes using the + | convention "attribute.rule" to name the lines. This makes it quick to + | specify a specific custom language line for a given attribute rule. + | + */ + + 'custom' => [ + 'password-confirm' => [ + 'required_with' => 'Confirmação de senha requerida', + ], + ], + + /* + |-------------------------------------------------------------------------- + | Custom Validation Attributes + |-------------------------------------------------------------------------- + | + | The following language lines are used to swap attribute place-holders + | with something more reader friendly such as E-Mail Address instead + | of "email". This simply helps us make messages a little cleaner. + | + */ + + 'attributes' => [], + +]; diff --git a/resources/views/home.blade.php b/resources/views/home.blade.php index 6f4009f72..49cd2a75a 100644 --- a/resources/views/home.blade.php +++ b/resources/views/home.blade.php @@ -65,4 +65,4 @@ -@stop \ No newline at end of file +@stop diff --git a/resources/views/pages/page-display.blade.php b/resources/views/pages/page-display.blade.php index fb6ca3045..6eb927687 100644 --- a/resources/views/pages/page-display.blade.php +++ b/resources/views/pages/page-display.blade.php @@ -7,6 +7,6 @@ @if (isset($diff) && $diff) {!! $diff !!} @else - {!! $page->html !!} + {!! isset($pageContent) ? $pageContent : $page->html !!} @endif \ No newline at end of file diff --git a/resources/views/pages/show.blade.php b/resources/views/pages/show.blade.php index a734b1b95..fd6cebf41 100644 --- a/resources/views/pages/show.blade.php +++ b/resources/views/pages/show.blade.php @@ -53,9 +53,9 @@
- - - + + +
diff --git a/resources/views/pages/sidebar-tree-list.blade.php b/resources/views/pages/sidebar-tree-list.blade.php index 0fb97369e..f366e9e9b 100644 --- a/resources/views/pages/sidebar-tree-list.blade.php +++ b/resources/views/pages/sidebar-tree-list.blade.php @@ -26,7 +26,7 @@ @endforeach @endif - @if (isset($pageNav) && $pageNav) + @if (isset($pageNav) && count($pageNav))
{{ trans('entities.pages_navigation') }}
diff --git a/resources/views/users/create.blade.php b/resources/views/users/create.blade.php index bff79820a..de3a3151f 100644 --- a/resources/views/users/create.blade.php +++ b/resources/views/users/create.blade.php @@ -8,7 +8,7 @@
@@ -16,7 +16,7 @@
-

Create User

+

{{ trans('settings.users_add_new') }}

{!! csrf_field() !!} diff --git a/resources/views/users/edit.blade.php b/resources/views/users/edit.blade.php index 4db00e31f..c5d512725 100644 --- a/resources/views/users/edit.blade.php +++ b/resources/views/users/edit.blade.php @@ -5,8 +5,6 @@ @include('settings/navbar', ['selected' => 'users']) - -
id}") }}" method="post">
@@ -42,7 +40,14 @@ 'name' => 'image_id', 'imageClass' => 'avatar large' ]) - +
+
+ +
diff --git a/tests/ActivityTrackingTest.php b/tests/ActivityTrackingTest.php index 8ee20ab6b..137317996 100644 --- a/tests/ActivityTrackingTest.php +++ b/tests/ActivityTrackingTest.php @@ -1,10 +1,7 @@ visit('/login')->click('Forgot Password?') ->seePageIs('/password/email') ->type('admin@admin.com', 'email') @@ -230,8 +233,13 @@ class AuthTest extends TestCase 'email' => 'admin@admin.com' ]); + $user = \BookStack\User::where('email', '=', 'admin@admin.com')->first(); + + Notification::assertSentTo($user, \BookStack\Notifications\ResetPassword::class); + $n = Notification::sent($user, \BookStack\Notifications\ResetPassword::class); + $reset = DB::table('password_resets')->where('email', '=', 'admin@admin.com')->first(); - $this->visit('/password/reset/' . $reset->token) + $this->visit('/password/reset/' . $n->first()->token) ->see('Reset Password') ->submitForm('Reset Password', [ 'email' => 'admin@admin.com', diff --git a/tests/Auth/LdapTest.php b/tests/Auth/LdapTest.php index 45e46fe81..80d0c9fe2 100644 --- a/tests/Auth/LdapTest.php +++ b/tests/Auth/LdapTest.php @@ -1,9 +1,7 @@ make(Illuminate\Contracts\Console\Kernel::class)->bootstrap(); + + return $app; + } + + /** + * Set the current user context to be an admin. + * @return $this + */ + public function asAdmin() + { + return $this->actingAs($this->getAdmin()); + } + + /** + * Get the current admin user. + * @return mixed + */ + public function getAdmin() { + if($this->admin === null) { + $adminRole = \BookStack\Role::getRole('admin'); + $this->admin = $adminRole->users->first(); + } + return $this->admin; + } + + /** + * Set the current editor context to be an editor. + * @return $this + */ + public function asEditor() + { + if ($this->editor === null) { + $this->editor = $this->getEditor(); + } + return $this->actingAs($this->editor); + } + + /** + * Get a user that's not a system user such as the guest user. + */ + public function getNormalUser() + { + return \BookStack\User::where('system_name', '=', null)->get()->last(); + } + + /** + * Quickly sets an array of settings. + * @param $settingsArray + */ + protected function setSettings($settingsArray) + { + $settings = app('BookStack\Services\SettingService'); + foreach ($settingsArray as $key => $value) { + $settings->put($key, $value); + } + } + + /** + * Create a group of entities that belong to a specific user. + * @param $creatorUser + * @param $updaterUser + * @return array + */ + protected function createEntityChainBelongingToUser($creatorUser, $updaterUser = false) + { + if ($updaterUser === false) $updaterUser = $creatorUser; + $book = factory(BookStack\Book::class)->create(['created_by' => $creatorUser->id, 'updated_by' => $updaterUser->id]); + $chapter = factory(BookStack\Chapter::class)->create(['created_by' => $creatorUser->id, 'updated_by' => $updaterUser->id]); + $page = factory(BookStack\Page::class)->create(['created_by' => $creatorUser->id, 'updated_by' => $updaterUser->id, 'book_id' => $book->id]); + $book->chapters()->saveMany([$chapter]); + $chapter->pages()->saveMany([$page]); + $restrictionService = $this->app[\BookStack\Services\PermissionService::class]; + $restrictionService->buildJointPermissionsForEntity($book); + return [ + 'book' => $book, + 'chapter' => $chapter, + 'page' => $page + ]; + } + + /** + * Quick way to create a new user + * @param array $attributes + * @return mixed + */ + protected function getEditor($attributes = []) + { + $user = factory(\BookStack\User::class)->create($attributes); + $role = \BookStack\Role::getRole('editor'); + $user->attachRole($role);; + return $user; + } + + /** + * Quick way to create a new user without any permissions + * @param array $attributes + * @return mixed + */ + protected function getNewBlankUser($attributes = []) + { + $user = factory(\BookStack\User::class)->create($attributes); + return $user; + } + + /** + * Assert that a given string is seen inside an element. + * + * @param bool|string|null $element + * @param integer $position + * @param string $text + * @param bool $negate + * @return $this + */ + protected function seeInNthElement($element, $position, $text, $negate = false) + { + $method = $negate ? 'assertNotRegExp' : 'assertRegExp'; + + $rawPattern = preg_quote($text, '/'); + + $escapedPattern = preg_quote(e($text), '/'); + + $content = $this->crawler->filter($element)->eq($position)->html(); + + $pattern = $rawPattern == $escapedPattern + ? $rawPattern : "({$rawPattern}|{$escapedPattern})"; + + $this->$method("/$pattern/i", $content); + + return $this; + } + + /** + * Assert that the current page matches a given URI. + * + * @param string $uri + * @return $this + */ + protected function seePageUrlIs($uri) + { + $this->assertEquals( + $uri, $this->currentUri, "Did not land on expected page [{$uri}].\n" + ); + + return $this; + } + + /** + * Do a forced visit that does not error out on exception. + * @param string $uri + * @param array $parameters + * @param array $cookies + * @param array $files + * @return $this + */ + protected function forceVisit($uri, $parameters = [], $cookies = [], $files = []) + { + $method = 'GET'; + $uri = $this->prepareUrlForRequest($uri); + $this->call($method, $uri, $parameters, $cookies, $files); + $this->clearInputs()->followRedirects(); + $this->currentUri = $this->app->make('request')->fullUrl(); + $this->crawler = new Crawler($this->response->getContent(), $uri); + return $this; + } + + /** + * Click the text within the selected element. + * @param $parentElement + * @param $linkText + * @return $this + */ + protected function clickInElement($parentElement, $linkText) + { + $elem = $this->crawler->filter($parentElement); + $link = $elem->selectLink($linkText); + $this->visit($link->link()->getUri()); + return $this; + } + + /** + * Check if the page contains the given element. + * @param string $selector + * @return bool + */ + protected function pageHasElement($selector) + { + $elements = $this->crawler->filter($selector); + $this->assertTrue(count($elements) > 0, "The page does not contain an element matching " . $selector); + return $this; + } + + /** + * Check if the page contains the given element. + * @param string $selector + * @return bool + */ + protected function pageNotHasElement($selector) + { + $elements = $this->crawler->filter($selector); + $this->assertFalse(count($elements) > 0, "The page contains " . count($elements) . " elements matching " . $selector); + return $this; + } +} diff --git a/tests/Entity/EntitySearchTest.php b/tests/Entity/EntitySearchTest.php index 3f60f9c36..23351e546 100644 --- a/tests/Entity/EntitySearchTest.php +++ b/tests/Entity/EntitySearchTest.php @@ -1,8 +1,6 @@ get(2); + + $secondPage->html = "

Hello, This is a test

This is a second block of content

"; + $secondPage->save(); + + $this->asAdmin()->visit($page->getUrl()) + ->dontSee('Hello, This is a test'); + + $originalHtml = $page->html; + $page->html .= "{{@{$secondPage->id}}}"; + $page->save(); + + $this->asAdmin()->visit($page->getUrl()) + ->see('Hello, This is a test') + ->see('This is a second block of content'); + + $page->html = $originalHtml . " Well {{@{$secondPage->id}#section2}}"; + $page->save(); + + $this->asAdmin()->visit($page->getUrl()) + ->dontSee('Hello, This is a test') + ->see('Well This is a second block of content'); + } + +} diff --git a/tests/Entity/PageDraftTest.php b/tests/Entity/PageDraftTest.php index 233f300ee..de875c3f3 100644 --- a/tests/Entity/PageDraftTest.php +++ b/tests/Entity/PageDraftTest.php @@ -1,7 +1,7 @@ merge(factory(Tag::class, 5)->make(['name' => 'color'])); $page = $this->getPageWithTags($attrs); - $this->asAdmin()->get('/ajax/tags/suggest?search=co')->seeJsonEquals(['color', 'country']); - $this->asEditor()->get('/ajax/tags/suggest?search=co')->seeJsonEquals(['color', 'country']); + $this->asAdmin()->get('/ajax/tags/suggest/names?search=co')->seeJsonEquals(['color', 'country']); + $this->asEditor()->get('/ajax/tags/suggest/names?search=co')->seeJsonEquals(['color', 'country']); // Set restricted permission the page $page->restricted = true; $page->save(); $permissionService->buildJointPermissionsForEntity($page); - $this->asAdmin()->get('/ajax/tags/suggest?search=co')->seeJsonEquals(['color', 'country']); - $this->asEditor()->get('/ajax/tags/suggest?search=co')->seeJsonEquals([]); - } - - public function test_entity_tag_updating() - { - $page = $this->getPageWithTags(); - - $testJsonData = [ - ['name' => 'color', 'value' => 'red'], - ['name' => 'color', 'value' => ' blue '], - ['name' => 'city', 'value' => 'London '], - ['name' => 'country', 'value' => ' England'], - ]; - $testResponseJsonData = [ - ['name' => 'color', 'value' => 'red'], - ['name' => 'color', 'value' => 'blue'], - ['name' => 'city', 'value' => 'London'], - ['name' => 'country', 'value' => 'England'], - ]; - - // Do update request - $this->asAdmin()->json("POST", "/ajax/tags/update/page/" . $page->id, ['tags' => $testJsonData]); - $updateData = json_decode($this->response->getContent()); - // Check data is correct - $testDataCorrect = true; - foreach ($updateData->tags as $data) { - $testItem = ['name' => $data->name, 'value' => $data->value]; - if (!in_array($testItem, $testResponseJsonData)) $testDataCorrect = false; - } - $testMessage = "Expected data was not found in the response.\nExpected Data: %s\nRecieved Data: %s"; - $this->assertTrue($testDataCorrect, sprintf($testMessage, json_encode($testResponseJsonData), json_encode($updateData))); - $this->assertTrue(isset($updateData->message), "No message returned in tag update response"); - - // Do get request - $this->asAdmin()->get("/ajax/tags/get/page/" . $page->id); - $getResponseData = json_decode($this->response->getContent()); - // Check counts - $this->assertTrue(count($getResponseData) === count($testJsonData), "The received tag count is incorrect"); - // Check data is correct - $testDataCorrect = true; - foreach ($getResponseData as $data) { - $testItem = ['name' => $data->name, 'value' => $data->value]; - if (!in_array($testItem, $testResponseJsonData)) $testDataCorrect = false; - } - $testMessage = "Expected data was not found in the response.\nExpected Data: %s\nRecieved Data: %s"; - $this->assertTrue($testDataCorrect, sprintf($testMessage, json_encode($testResponseJsonData), json_encode($getResponseData))); + $this->asAdmin()->get('/ajax/tags/suggest/names?search=co')->seeJsonEquals(['color', 'country']); + $this->asEditor()->get('/ajax/tags/suggest/names?search=co')->seeJsonEquals([]); } } diff --git a/tests/ImageTest.php b/tests/ImageTest.php index 9da12d36b..debde848c 100644 --- a/tests/ImageTest.php +++ b/tests/ImageTest.php @@ -1,6 +1,6 @@ see('Cannot be deleted'); } + + + public function test_image_delete_own_permission() + { + $this->giveUserPermissions($this->user, ['image-update-all']); + $page = \BookStack\Page::first(); + $image = factory(\BookStack\Image::class)->create(['uploaded_to' => $page->id, 'created_by' => $this->user->id, 'updated_by' => $this->user->id]); + + $this->actingAs($this->user)->json('delete', '/images/' . $image->id) + ->seeStatusCode(403); + + $this->giveUserPermissions($this->user, ['image-delete-own']); + + $this->actingAs($this->user)->json('delete', '/images/' . $image->id) + ->seeStatusCode(200) + ->dontSeeInDatabase('images', ['id' => $image->id]); + } + + public function test_image_delete_all_permission() + { + $this->giveUserPermissions($this->user, ['image-update-all']); + $admin = $this->getAdmin(); + $page = \BookStack\Page::first(); + $image = factory(\BookStack\Image::class)->create(['uploaded_to' => $page->id, 'created_by' => $admin->id, 'updated_by' => $admin->id]); + + $this->actingAs($this->user)->json('delete', '/images/' . $image->id) + ->seeStatusCode(403); + + $this->giveUserPermissions($this->user, ['image-delete-own']); + + $this->actingAs($this->user)->json('delete', '/images/' . $image->id) + ->seeStatusCode(403); + + $this->giveUserPermissions($this->user, ['image-delete-all']); + + $this->actingAs($this->user)->json('delete', '/images/' . $image->id) + ->seeStatusCode(200) + ->dontSeeInDatabase('images', ['id' => $image->id]); + } + } diff --git a/tests/PublicActionTest.php b/tests/PublicActionTest.php index 2ea5fbfed..6127e1cd4 100644 --- a/tests/PublicActionTest.php +++ b/tests/PublicActionTest.php @@ -1,6 +1,6 @@ make(Illuminate\Contracts\Console\Kernel::class)->bootstrap(); + $app->make(Kernel::class)->bootstrap(); return $app; } - - /** - * Set the current user context to be an admin. - * @return $this - */ - public function asAdmin() - { - return $this->actingAs($this->getAdmin()); - } - - /** - * Get the current admin user. - * @return mixed - */ - public function getAdmin() { - if($this->admin === null) { - $adminRole = \BookStack\Role::getRole('admin'); - $this->admin = $adminRole->users->first(); - } - return $this->admin; - } - - /** - * Set the current editor context to be an editor. - * @return $this - */ - public function asEditor() - { - if($this->editor === null) { - $this->editor = $this->getEditor(); - } - return $this->actingAs($this->editor); - } - - /** - * Get a user that's not a system user such as the guest user. - */ - public function getNormalUser() - { - return \BookStack\User::where('system_name', '=', null)->get()->last(); - } - - /** - * Quickly sets an array of settings. - * @param $settingsArray - */ - protected function setSettings($settingsArray) - { - $settings = app('BookStack\Services\SettingService'); - foreach ($settingsArray as $key => $value) { - $settings->put($key, $value); - } - } - - /** - * Create a group of entities that belong to a specific user. - * @param $creatorUser - * @param $updaterUser - * @return array - */ - protected function createEntityChainBelongingToUser($creatorUser, $updaterUser = false) - { - if ($updaterUser === false) $updaterUser = $creatorUser; - $book = factory(BookStack\Book::class)->create(['created_by' => $creatorUser->id, 'updated_by' => $updaterUser->id]); - $chapter = factory(BookStack\Chapter::class)->create(['created_by' => $creatorUser->id, 'updated_by' => $updaterUser->id]); - $page = factory(BookStack\Page::class)->create(['created_by' => $creatorUser->id, 'updated_by' => $updaterUser->id, 'book_id' => $book->id]); - $book->chapters()->saveMany([$chapter]); - $chapter->pages()->saveMany([$page]); - $restrictionService = $this->app[\BookStack\Services\PermissionService::class]; - $restrictionService->buildJointPermissionsForEntity($book); - return [ - 'book' => $book, - 'chapter' => $chapter, - 'page' => $page - ]; - } - - /** - * Quick way to create a new user - * @param array $attributes - * @return mixed - */ - protected function getEditor($attributes = []) - { - $user = factory(\BookStack\User::class)->create($attributes); - $role = \BookStack\Role::getRole('editor'); - $user->attachRole($role);; - return $user; - } - - /** - * Quick way to create a new user without any permissions - * @param array $attributes - * @return mixed - */ - protected function getNewBlankUser($attributes = []) - { - $user = factory(\BookStack\User::class)->create($attributes); - return $user; - } - - /** - * Assert that a given string is seen inside an element. - * - * @param bool|string|null $element - * @param integer $position - * @param string $text - * @param bool $negate - * @return $this - */ - protected function seeInNthElement($element, $position, $text, $negate = false) - { - $method = $negate ? 'assertNotRegExp' : 'assertRegExp'; - - $rawPattern = preg_quote($text, '/'); - - $escapedPattern = preg_quote(e($text), '/'); - - $content = $this->crawler->filter($element)->eq($position)->html(); - - $pattern = $rawPattern == $escapedPattern - ? $rawPattern : "({$rawPattern}|{$escapedPattern})"; - - $this->$method("/$pattern/i", $content); - - return $this; - } - - /** - * Assert that the current page matches a given URI. - * - * @param string $uri - * @return $this - */ - protected function seePageUrlIs($uri) - { - $this->assertEquals( - $uri, $this->currentUri, "Did not land on expected page [{$uri}].\n" - ); - - return $this; - } - - /** - * Do a forced visit that does not error out on exception. - * @param string $uri - * @param array $parameters - * @param array $cookies - * @param array $files - * @return $this - */ - protected function forceVisit($uri, $parameters = [], $cookies = [], $files = []) - { - $method = 'GET'; - $uri = $this->prepareUrlForRequest($uri); - $this->call($method, $uri, $parameters, $cookies, $files); - $this->clearInputs()->followRedirects(); - $this->currentUri = $this->app->make('request')->fullUrl(); - $this->crawler = new Crawler($this->response->getContent(), $uri); - return $this; - } - - /** - * Click the text within the selected element. - * @param $parentElement - * @param $linkText - * @return $this - */ - protected function clickInElement($parentElement, $linkText) - { - $elem = $this->crawler->filter($parentElement); - $link = $elem->selectLink($linkText); - $this->visit($link->link()->getUri()); - return $this; - } - - /** - * Check if the page contains the given element. - * @param string $selector - * @return bool - */ - protected function pageHasElement($selector) - { - $elements = $this->crawler->filter($selector); - $this->assertTrue(count($elements) > 0, "The page does not contain an element matching " . $selector); - return $this; - } - - /** - * Check if the page contains the given element. - * @param string $selector - * @return bool - */ - protected function pageNotHasElement($selector) - { - $elements = $this->crawler->filter($selector); - $this->assertFalse(count($elements) > 0, "The page contains " . count($elements) . " elements matching " . $selector); - return $this; - } } diff --git a/tests/UserProfileTest.php b/tests/UserProfileTest.php index 9543adc1d..a448e3a9f 100644 --- a/tests/UserProfileTest.php +++ b/tests/UserProfileTest.php @@ -1,6 +1,6 @@