Merge branch 'release/0.15.3'

This commit is contained in:
Jonny Barnes 2018-01-12 21:42:18 +00:00
commit 090f33fe67
28 changed files with 352 additions and 63 deletions

View file

@ -0,0 +1,63 @@
<?php
declare(strict_types=1);
namespace App\Http\Controllers\Admin;
use App\Models\Like;
use App\Jobs\ProcessLike;
use Illuminate\View\View;
use App\Http\Controllers\Controller;
use Illuminate\Http\RedirectResponse;
class LikesController extends Controller
{
public function index(): View
{
$likes = Like::all();
return view('admin.likes.index', compact('likes'));
}
public function create(): View
{
return view('admin.likes.create');
}
public function store(): RedirectResponse
{
$like = Like::create([
'url' => normalize_url(request()->input('like_url')),
]);
ProcessLike::dispatch($like);
return redirect('/admin/likes');
}
public function edit(int $likeId): View
{
$like = Like::findOrFail($likeId);
return view('admin.likes.edit', [
'id' => $like->id,
'like_url' => $like->url,
]);
}
public function update(int $likeId): RedirectResponse
{
$like = Like::findOrFail($likeId);
$like->url = normalize_url(request()->input('like_url'));
$like->save();
ProcessLike::dispatch($like);
return redirect('/admin/likes');
}
public function destroy(int $likeId): RedirectResponse
{
Like::where('id', $likeId)->delete();
return redirect('/admin/likes');
}
}

View file

@ -5,8 +5,10 @@ namespace App\Jobs;
use App\Models\Like;
use GuzzleHttp\Client;
use Illuminate\Bus\Queueable;
use Thujohn\Twitter\Facades\Twitter;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use GuzzleHttp\Exception\ClientException;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Jonnybarnes\WebmentionsParser\Authorship;
@ -35,6 +37,32 @@ class ProcessLike implements ShouldQueue
*/
public function handle(Client $client, Authorship $authorship)
{
if ($this->isTweet($this->like->url)) {
$tweet = Twitter::getOembed(['url' => $this->like->url]);
$this->like->author_name = $tweet->author_name;
$this->like->author_url = $tweet->author_url;
$this->like->content = $tweet->html;
$this->like->save();
//POSSE like
try {
$response = $client->request(
'POST',
'https://brid.gy/publish/webmention',
[
'form_params' => [
'source' => $this->like->url,
'target' => 'https://brid.gy/publish/twitter',
],
]
);
} catch (ClientException $exception) {
//no biggie
}
return 0;
}
$response = $client->request('GET', $this->like->url);
$mf2 = \Mf2\parse((string) $response->getBody(), $this->like->url);
if (array_has($mf2, 'items.0.properties.content')) {
@ -51,9 +79,17 @@ class ProcessLike implements ShouldQueue
$this->like->author_name = $author;
}
} catch (AuthorshipParserException $exception) {
return;
return 1;
}
$this->like->save();
}
private function isTweet(string $url): bool
{
$host = parse_url($url, PHP_URL_HOST);
$parts = array_reverse(explode('.', $host));
return $parts[0] === 'com' && $parts[1] === 'twitter';
}
}

View file

@ -29,7 +29,13 @@ class Like extends Model
$mf2 = Mf2\parse($value, $this->url);
return $this->filterHTML($mf2['items'][0]['properties']['content'][0]['html']);
if (array_get($mf2, 'items.0.properties.content.0.html')) {
return $this->filterHTML(
$mf2['items'][0]['properties']['content'][0]['html']
);
}
return $value;
}
public function filterHTML($html)

View file

@ -1,5 +1,9 @@
# Changelog
## Version 0.15.3 (2018-01-12)
- Improve `likes`, including adding a new section in the admin cp
- Add the ability to POSSE the like of a Tweet
## Version 0.15.2 (2018-01-11)
- Update micropub endpoint to support access tokens being sent in either acceptable form
- Improve admin control panel forms

62
composer.lock generated
View file

@ -8,16 +8,16 @@
"packages": [
{
"name": "aws/aws-sdk-php",
"version": "3.48.11",
"version": "3.48.12",
"source": {
"type": "git",
"url": "https://github.com/aws/aws-sdk-php.git",
"reference": "4159562ee5c2b2d322cfcccd2401d90bfaceaf1d"
"reference": "c7f3148d537db877e9b4b63308d61f52eaa253bc"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/4159562ee5c2b2d322cfcccd2401d90bfaceaf1d",
"reference": "4159562ee5c2b2d322cfcccd2401d90bfaceaf1d",
"url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/c7f3148d537db877e9b4b63308d61f52eaa253bc",
"reference": "c7f3148d537db877e9b4b63308d61f52eaa253bc",
"shasum": ""
},
"require": {
@ -84,7 +84,7 @@
"s3",
"sdk"
],
"time": "2018-01-09T22:01:13+00:00"
"time": "2018-01-11T20:40:29+00:00"
},
{
"name": "barnabywalters/mf-cleaner",
@ -3811,25 +3811,25 @@
},
{
"name": "symfony/css-selector",
"version": "v3.4.3",
"version": "v4.0.3",
"source": {
"type": "git",
"url": "https://github.com/symfony/css-selector.git",
"reference": "e66394bc7610e69279bfdb3ab11b4fe65403f556"
"reference": "f97600434e3141ef3cbb9ea42cf500fba88022b7"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/css-selector/zipball/e66394bc7610e69279bfdb3ab11b4fe65403f556",
"reference": "e66394bc7610e69279bfdb3ab11b4fe65403f556",
"url": "https://api.github.com/repos/symfony/css-selector/zipball/f97600434e3141ef3cbb9ea42cf500fba88022b7",
"reference": "f97600434e3141ef3cbb9ea42cf500fba88022b7",
"shasum": ""
},
"require": {
"php": "^5.5.9|>=7.0.8"
"php": "^7.1.3"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "3.4-dev"
"dev-master": "4.0-dev"
}
},
"autoload": {
@ -3860,7 +3860,7 @@
],
"description": "Symfony CssSelector Component",
"homepage": "https://symfony.com",
"time": "2018-01-03T07:37:34+00:00"
"time": "2018-01-03T07:38:00+00:00"
},
{
"name": "symfony/debug",
@ -4642,29 +4642,29 @@
},
{
"name": "tijsverkoyen/css-to-inline-styles",
"version": "2.2.0",
"version": "2.2.1",
"source": {
"type": "git",
"url": "https://github.com/tijsverkoyen/CssToInlineStyles.git",
"reference": "ab03919dfd85a74ae0372f8baf9f3c7d5c03b04b"
"reference": "0ed4a2ea4e0902dac0489e6436ebcd5bbcae9757"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/tijsverkoyen/CssToInlineStyles/zipball/ab03919dfd85a74ae0372f8baf9f3c7d5c03b04b",
"reference": "ab03919dfd85a74ae0372f8baf9f3c7d5c03b04b",
"url": "https://api.github.com/repos/tijsverkoyen/CssToInlineStyles/zipball/0ed4a2ea4e0902dac0489e6436ebcd5bbcae9757",
"reference": "0ed4a2ea4e0902dac0489e6436ebcd5bbcae9757",
"shasum": ""
},
"require": {
"php": "^5.5 || ^7",
"symfony/css-selector": "^2.7|~3.0"
"php": "^5.5 || ^7.0",
"symfony/css-selector": "^2.7 || ^3.0 || ^4.0"
},
"require-dev": {
"phpunit/phpunit": "~4.8|5.1.*"
"phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.0.x-dev"
"dev-master": "2.2.x-dev"
}
},
"autoload": {
@ -4685,7 +4685,7 @@
],
"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-20T12:50:39+00:00"
"time": "2017-11-27T11:13:29+00:00"
},
{
"name": "vlucas/phpdotenv",
@ -4872,16 +4872,16 @@
},
{
"name": "codedungeon/phpunit-result-printer",
"version": "0.5.1",
"version": "0.5.3",
"source": {
"type": "git",
"url": "https://github.com/mikeerickson/phpunit-pretty-result-printer.git",
"reference": "2dcf5f220f1019ddb2a85995828f513205416e0d"
"reference": "f20153a255dcf444a8abe4ac3051aa35ef865b90"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/mikeerickson/phpunit-pretty-result-printer/zipball/2dcf5f220f1019ddb2a85995828f513205416e0d",
"reference": "2dcf5f220f1019ddb2a85995828f513205416e0d",
"url": "https://api.github.com/repos/mikeerickson/phpunit-pretty-result-printer/zipball/f20153a255dcf444a8abe4ac3051aa35ef865b90",
"reference": "f20153a255dcf444a8abe4ac3051aa35ef865b90",
"shasum": ""
},
"require": {
@ -4916,7 +4916,7 @@
"printer",
"result-printer"
],
"time": "2018-01-09T21:42:36+00:00"
"time": "2018-01-11T17:18:07+00:00"
},
{
"name": "container-interop/container-interop",
@ -6510,16 +6510,16 @@
},
{
"name": "sebastian/comparator",
"version": "2.1.1",
"version": "2.1.2",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/comparator.git",
"reference": "b11c729f95109b56a0fe9650c6a63a0fcd8c439f"
"reference": "11c07feade1d65453e06df3b3b90171d6d982087"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/b11c729f95109b56a0fe9650c6a63a0fcd8c439f",
"reference": "b11c729f95109b56a0fe9650c6a63a0fcd8c439f",
"url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/11c07feade1d65453e06df3b3b90171d6d982087",
"reference": "11c07feade1d65453e06df3b3b90171d6d982087",
"shasum": ""
},
"require": {
@ -6570,7 +6570,7 @@
"compare",
"equality"
],
"time": "2017-12-22T14:50:35+00:00"
"time": "2018-01-12T06:34:42+00:00"
},
{
"name": "sebastian/diff",

View file

@ -14,6 +14,7 @@ class LikesTableSeeder extends Seeder
public function run()
{
factory(Like::class, 10)->create();
sleep(1);
$faker = new Generator();
$faker->addProvider(new \Faker\Provider\en_US\Person($faker));
@ -24,5 +25,8 @@ class LikesTableSeeder extends Seeder
'author_url' => $faker->url,
'author_name' => $faker->name,
]);
sleep(1);
Like::create(['url' => 'https://example.com']);
}
}

View file

@ -126,20 +126,33 @@ if (! function_exists('normalize_url')) {
// Sort GET params alphabetically, not because the RFC requires it but because it's cool!
if (isset($url['query'])) {
if (preg_match('/&/', $url['query'])) {
$s = explode('&', $url['query']);
$url['query'] = '';
sort($s);
foreach ($s as $z) {
$url['query'] .= "{$z}&";
$queries = explode('&', $url['query']);
$url['query'] = '';
sort($queries);
foreach ($queries as $query) {
//lets drop query params we dont want
$key = stristr($query, '=', true);
if (queryKeyIsBanned($key) === false) {
$url['query'] .= "{$query}&";
}
$url['query'] = preg_replace('/&\Z/', '', $url['query']);
}
$newUrl .= "?{$url['query']}";
$url['query'] = preg_replace('/&\Z/', '', $url['query']);
if ($url['query'] !== '') {
$newUrl .= "?{$url['query']}";
}
}
return $newUrl;
}
function queryKeyIsBanned(string $key): bool
{
$bannedKeys = [
'ref_src',
];
return in_array($key, $bannedKeys);
}
}
// sourced from https://stackoverflow.com/a/9776726

6
package-lock.json generated
View file

@ -5835,9 +5835,9 @@
"dev": true
},
"marked": {
"version": "0.3.9",
"resolved": "https://registry.npmjs.org/marked/-/marked-0.3.9.tgz",
"integrity": "sha512-nW5u0dxpXxHfkHzzrveY45gCbi+R4PaO4WRZYqZNl+vB0hVGeqlFn0aOg1c8AKL63TrNFn9Bm2UP4AdiZ9TPLw=="
"version": "0.3.12",
"resolved": "https://registry.npmjs.org/marked/-/marked-0.3.12.tgz",
"integrity": "sha512-k4NaW+vS7ytQn6MgJn3fYpQt20/mOgYM5Ft9BYMfQJDz2QT6yEeS9XJ8k2Nw8JTeWK/znPPW2n3UJGzyYEiMoA=="
},
"mathml-tag-names": {
"version": "2.0.1",

View file

@ -7,7 +7,7 @@
"dependencies": {
"alertify.js": "^1.0.12",
"mapbox-gl": "^0.42.2",
"marked": "^0.3.9",
"marked": "^0.3.12",
"normalize.css": "^7.0.0"
},
"devDependencies": {

File diff suppressed because one or more lines are too long

Binary file not shown.

Binary file not shown.

View file

@ -1 +1 @@
{"version":3,"sources":["../../../resources/assets/sass/_border-box.scss","../../../resources/assets/sass/_base-font.scss","../../../resources/assets/sass/_header.scss","../../../resources/assets/sass/_variables.scss","../../../resources/assets/sass/_main.scss","../../../resources/assets/sass/_hovercard.scss","../../../resources/assets/sass/_notes.scss","../../../resources/assets/sass/_pagination.scss","../../../resources/assets/sass/_contacts-page.scss","../../../resources/assets/sass/_projects.scss","../../../resources/assets/sass/_footer.scss","../../../resources/assets/sass/_admin-form.scss","../../../resources/assets/sass/_form.scss","../../../resources/assets/sass/_bridgy-links.scss","../../../resources/assets/sass/_emoji.scss","../../../resources/assets/sass/_mapbox.scss","../../../resources/assets/sass/_colors.scss","../../../resources/assets/sass/_styles.scss","../../../resources/assets/sass/_tags.scss"],"names":[],"mappings":"AAKA,KACI,8BAAsB,AAAtB,qBAAsB,CACzB,qBAKG,2BAAmB,AAAnB,kBAAmB,CACtB,KCVG,eACA,gCAAiC,CACpC,gBAGG,oBAAqB,CACxB,WCNG,oBACA,AADA,oBACA,AADA,aACA,8BACA,AADA,6BACA,AADA,kBACA,AADA,cACA,yBACA,AADA,sBACA,AADA,mBACA,WACA,eCJgB,CDKnB,cAGG,eACA,cAAe,CAClB,eAGG,cAAe,CAClB,KEdG,oBACA,AADA,oBACA,AADA,aACA,4BACA,AADA,6BACA,AADA,0BACA,AADA,sBACA,0BACA,AADA,uBACA,AADA,oBACA,gBACA,cACA,iBACA,cAAe,CAClB,WAIG,gBAAiB,CACpB,aCZG,iBAAkB,CACrB,qBAGG,iBAAkB,CACrB,2BAGG,WAAY,CACf,WAGG,kBACA,8BACA,AADA,6BACA,AADA,uBACA,AADA,mBACA,yBACA,AADA,sBACA,AADA,8BACA,sBACA,AADA,mBACA,AADA,qBACA,iBACA,YACA,WACA,UACA,WACA,uBACA,kBACA,2CACA,AADA,mCACA,YAAa,CAChB,8BAGG,oBAAa,AAAb,oBAAa,AAAb,YAAa,CAChB,0BAGG,WACA,WAAY,CACf,sBAGG,YAAa,CCnCjB,MACI,oBACA,AADA,oBACA,AADA,aACA,4BACA,AADA,6BACA,AADA,0BACA,AADA,sBACA,cAAe,CAClB,UAGG,eACA,eAAgB,CACnB,eAGG,oBACA,AADA,oBACA,AADA,aACA,8BACA,AADA,6BACA,AADA,uBACA,AADA,mBACA,yBAA8B,AAA9B,sBAA8B,AAA9B,6BAA8B,CACjC,MAGG,WACA,UAAW,CACd,YCtBG,oBACA,AADA,oBACA,AADA,aACA,8BACA,AADA,6BACA,AADA,uBACA,AADA,mBACA,8BACA,AADA,2BACA,AADA,6BACA,eACA,oBAAqB,CACxB,cCLG,eACA,oBACA,AADA,oBACA,AADA,aACA,8BACA,AADA,8BACA,AADA,+BACA,AADA,2BACA,yBACA,AADA,sBACA,AADA,8BACA,eAAgB,CACnB,kBAGG,WACA,WAAY,CACf,UCVG,cAAe,CAClB,gBCDG,gBACA,cACA,gBAAiB,CACpB,OAGG,gBACA,cACA,oBACA,AADA,oBACA,AADA,aACA,4BACA,AADA,6BACA,AADA,0BACA,AADA,sBACA,yBAAmB,AAAnB,sBAAmB,AAAnB,kBAAmB,CACtB,YCXG,gBACA,kBAAmB,CACtB,MCFG,oBACA,AADA,oBACA,AADA,aACA,4BAAsB,AAAtB,6BAAsB,AAAtB,0BAAsB,AAAtB,qBAAsB,CACzB,UAGG,oBACA,AADA,oBACA,AADA,aACA,4BAAsB,AAAtB,6BAAsB,AAAtB,0BAAsB,AAAtB,qBAAsB,CACzB,aAGG,8BAAmB,AAAnB,6BAAmB,AAAnB,uBAAmB,AAAnB,kBAAmB,CACtB,qDCVG,YAAa,CAChB,2BCAG,iBAAkB,CACrB,gFAIG,kBACA,cACA,UACA,aACA,OACA,cACA,qBACA,yBACA,oBACA,4CACA,AADA,oCACA,yBACA,kCACA,WACA,cACA,0CAAkC,AAAlC,iCAAkC,CACrC,2BAGG,KACI,aACA,6BACA,wCACA,0BACA,8BAAkC,AAAlC,qBAAkC,CAGtC,GACI,aACA,kCACA,yBACA,WACA,4CAAgD,AAAhD,mCAAgD,CAAA,CAIxD,AApBC,mBAGG,KACI,aACA,6BACA,wCACA,0BACA,8BAAkC,AAAlC,qBAAkC,CAGtC,GACI,aACA,kCACA,yBACA,WACA,4CAAgD,AAAhD,mCAAgD,CAAA,CAIxD,aACI,kCACI,kCAAmC,CACtC,CC9CL,KACI,YAAa,CAChB,oBAGG,kBAAmB,CACtB,QAGG,y4HACA,wBACA,WACA,WAAY,CACf,UAGG,kBACA,MACA,OACA,iBACA,cAAe,CAClB,gBAGG,gBACA,gBAAiB,CACpB,KCzBG,gCACA,kBAAmB,CACtB,WAGG,8BACA,kBAAmB,CACtB,YAIG,iBAAkB,CACrB,KCZG,oBAAqB,CACxB,aAGG,oBAAqB,CACxB,MCHG,SACA,gBACA,SAAU,CACb,SAGG,WACA,oBAAqB,CACxB,kBAIG,wBACA,0BACA,mBACA,qBACA,cACA,mBACA,sBACA,kBACA,qBACA,qBACA,8BAAsB,AAAtB,qBAAsB,CACzB,YAGG,0BACA,uCACA,oCACA,oCACA,WACA,kBACA,QACA,KAAM,CACT,WAGG,4BACA,kBAAmB,CACtB,kBAGG,4BAA6B,CAChC","file":"app.css"}
{"version":3,"sources":["../../../resources/assets/sass/_border-box.scss","../../../resources/assets/sass/_base-font.scss","../../../resources/assets/sass/_header.scss","../../../resources/assets/sass/_variables.scss","../../../resources/assets/sass/_main.scss","../../../resources/assets/sass/_hovercard.scss","../../../resources/assets/sass/_notes.scss","../../../resources/assets/sass/_pagination.scss","../../../resources/assets/sass/_contacts-page.scss","../../../resources/assets/sass/_projects.scss","../../../resources/assets/sass/_footer.scss","../../../resources/assets/sass/_admin-form.scss","../../../resources/assets/sass/_form.scss","../../../resources/assets/sass/_likes.scss","../../../resources/assets/sass/_bridgy-links.scss","../../../resources/assets/sass/_emoji.scss","../../../resources/assets/sass/_mapbox.scss","../../../resources/assets/sass/_colors.scss","../../../resources/assets/sass/_styles.scss","../../../resources/assets/sass/_tags.scss"],"names":[],"mappings":"AAKA,KACI,8BAAsB,AAAtB,qBAAsB,CACzB,qBAKG,2BAAmB,AAAnB,kBAAmB,CACtB,KCVG,eACA,gCAAiC,CACpC,gBAGG,oBAAqB,CACxB,WCNG,oBACA,AADA,oBACA,AADA,aACA,8BACA,AADA,6BACA,AADA,kBACA,AADA,cACA,yBACA,AADA,sBACA,AADA,mBACA,WACA,eCJgB,CDKnB,cAGG,eACA,cAAe,CAClB,eAGG,cAAe,CAClB,KEdG,oBACA,AADA,oBACA,AADA,aACA,4BACA,AADA,6BACA,AADA,0BACA,AADA,sBACA,0BACA,AADA,uBACA,AADA,oBACA,gBACA,cACA,iBACA,cAAe,CAClB,WAIG,gBAAiB,CACpB,aCZG,iBAAkB,CACrB,qBAGG,iBAAkB,CACrB,2BAGG,WAAY,CACf,WAGG,kBACA,8BACA,AADA,6BACA,AADA,uBACA,AADA,mBACA,yBACA,AADA,sBACA,AADA,8BACA,sBACA,AADA,mBACA,AADA,qBACA,iBACA,YACA,WACA,UACA,WACA,uBACA,kBACA,2CACA,AADA,mCACA,YAAa,CAChB,8BAGG,oBAAa,AAAb,oBAAa,AAAb,YAAa,CAChB,0BAGG,WACA,WAAY,CACf,sBAGG,YAAa,CCnCjB,MACI,oBACA,AADA,oBACA,AADA,aACA,4BACA,AADA,6BACA,AADA,0BACA,AADA,sBACA,cAAe,CAClB,UAGG,eACA,eAAgB,CACnB,eAGG,oBACA,AADA,oBACA,AADA,aACA,8BACA,AADA,6BACA,AADA,uBACA,AADA,mBACA,yBAA8B,AAA9B,sBAA8B,AAA9B,6BAA8B,CACjC,MAGG,WACA,UAAW,CACd,YCtBG,oBACA,AADA,oBACA,AADA,aACA,8BACA,AADA,6BACA,AADA,uBACA,AADA,mBACA,8BACA,AADA,2BACA,AADA,6BACA,eACA,oBAAqB,CACxB,cCLG,eACA,oBACA,AADA,oBACA,AADA,aACA,8BACA,AADA,8BACA,AADA,+BACA,AADA,2BACA,yBACA,AADA,sBACA,AADA,8BACA,eAAgB,CACnB,kBAGG,WACA,WAAY,CACf,UCVG,cAAe,CAClB,gBCDG,gBACA,cACA,gBAAiB,CACpB,OAGG,gBACA,cACA,oBACA,AADA,oBACA,AADA,aACA,4BACA,AADA,6BACA,AADA,0BACA,AADA,sBACA,yBAAmB,AAAnB,sBAAmB,AAAnB,kBAAmB,CACtB,YCXG,gBACA,kBAAmB,CACtB,MCFG,oBACA,AADA,oBACA,AADA,aACA,4BAAsB,AAAtB,6BAAsB,AAAtB,0BAAsB,AAAtB,qBAAsB,CACzB,UAGG,oBACA,AADA,oBACA,AADA,aACA,4BAAsB,AAAtB,6BAAsB,AAAtB,0BAAsB,AAAtB,qBAAsB,CACzB,aAGG,8BAAmB,AAAnB,6BAAmB,AAAnB,uBAAmB,AAAnB,kBAAmB,CACtB,WCXG,eAAgB,CACnB,qDCAG,YAAa,CAChB,2BCAG,iBAAkB,CACrB,gFAIG,kBACA,cACA,UACA,aACA,OACA,cACA,qBACA,yBACA,oBACA,4CACA,AADA,oCACA,yBACA,kCACA,WACA,cACA,0CAAkC,AAAlC,iCAAkC,CACrC,2BAGG,KACI,aACA,6BACA,wCACA,0BACA,8BAAkC,AAAlC,qBAAkC,CAGtC,GACI,aACA,kCACA,yBACA,WACA,4CAAgD,AAAhD,mCAAgD,CAAA,CAIxD,AApBC,mBAGG,KACI,aACA,6BACA,wCACA,0BACA,8BAAkC,AAAlC,qBAAkC,CAGtC,GACI,aACA,kCACA,yBACA,WACA,4CAAgD,AAAhD,mCAAgD,CAAA,CAIxD,aACI,kCACI,kCAAmC,CACtC,CC9CL,KACI,YAAa,CAChB,oBAGG,kBAAmB,CACtB,QAGG,y4HACA,wBACA,WACA,WAAY,CACf,UAGG,kBACA,MACA,OACA,iBACA,cAAe,CAClB,gBAGG,gBACA,gBAAiB,CACpB,KCzBG,gCACA,kBAAmB,CACtB,WAGG,8BACA,kBAAmB,CACtB,YAIG,iBAAkB,CACrB,KCZG,oBAAqB,CACxB,aAGG,oBAAqB,CACxB,MCHG,SACA,gBACA,SAAU,CACb,SAGG,WACA,oBAAqB,CACxB,kBAIG,wBACA,0BACA,mBACA,qBACA,cACA,mBACA,sBACA,kBACA,qBACA,qBACA,8BAAsB,AAAtB,qBAAsB,CACzB,YAGG,0BACA,uCACA,oCACA,oCACA,WACA,kBACA,QACA,KAAM,CACT,WAGG,4BACA,kBAAmB,CACtB,kBAGG,4BAA6B,CAChC","file":"app.css"}

File diff suppressed because one or more lines are too long

Binary file not shown.

Binary file not shown.

File diff suppressed because one or more lines are too long

5
resources/assets/sass/_likes.scss vendored Normal file
View file

@ -0,0 +1,5 @@
//likes.scss
.u-like-of {
margin-top: 1rem;
}

View file

@ -18,6 +18,7 @@
@import "footer";
@import "admin-form";
@import "form";
@import "likes";
//hide the custom bridgy posse content
@import "bridgy-links";

View file

@ -0,0 +1,17 @@
@extends('master')
@section('title')New Like « Admin CP « @stop
@section('content')
<h1>New Like</h1>
<form action="/admin/likes/" method="post" accept-charset="utf-8" class="admin-form form">
{{ csrf_field() }}
<div>
<label for="like_url">Like URL:</label>
<input type="text" name="like_url" id="like_url" placeholder="Like URL">
</div>
<div>
<button type="submit" name="submit">Submit</button>
</div>
</form>
@stop

View file

@ -0,0 +1,24 @@
@extends('master')
@section('title')Edit Like « Admin CP « @stop
@section('content')
<h1>Edit Like</h1>
<form action="/admin/likes/{{ $id }}" method="post" accept-charset="utf-8" class="admin-form form">
{{ csrf_field() }}
{{ method_field('PUT') }}
<div>
<label for="like_url">Like URL:</label>
<input type="text" name="like_url" id="like_url" value="{{ $like_url }}">
</div>
<div>
<button type="submit" name="edit">Edit</button>
</div>
</form>
<hr>
<form action="/admin/likes/{{ $id }}" method="post">
{{ csrf_field() }}
{{ method_field('DELETE') }}
<button type="submit" name="delete">Delete Like</button>
</form>
@stop

View file

@ -0,0 +1,15 @@
@extends('master')
@section('title')List Likes « Admin CP « @stop
@section('content')
<h1>Likes</h1>
<ul>
@foreach($likes as $like)
<li>{{ $like['url'] }}
<a href="/admin/likes/{{ $like['id'] }}/edit">edit?</a>
</li>
@endforeach
</ul>
<p>Create a <a href="/admin/likes/create">new like</a>?</p>
@stop

View file

@ -11,6 +11,9 @@
<h2>Notes</h2>
<p>You can either <a href="/admin/notes/create">create</a> new notes, or <a href="/admin/notes/">edit</a> them.<p>
<h2>Likes</h2>
<p>You can either <a href="/admin/likes/create">create</a> a new like, or <a href="/admin/likes/">edit</a> them.<p>
<h2>Clients</h2>
<p>You can either <a href="/admin/clients/create">create</a> new client names, or <a href="/admin/clients/">edit</a> them.</p>

View file

@ -3,18 +3,20 @@
@section('title')Likes « @stop
@section('content')
<div class="h-feed top-space">
<div class="h-feed">
@foreach($likes as $like)
<div class="h-entry">
<div class="h-cite u-like-of">
Liked <a class="u-url" href="{{ $like->url }}">a post</a> by
<span class="p-author h-card">
Liked <a class="u-url" href="{{ $like->url }}">a post</a>
@isset($like->author_name)
by <span class="p-author h-card">
@isset($like->author_url)
<a class="u-url p-name" href="{{ $like->author_url }}">{{ $like->author_name }}</a>
@else
<span class="p-name">{{ $like->author_name }}</span>
@endisset
</span>
@endisset
@isset($like->content)
<blockquote class="e-content">
{!! $like->content !!}

View file

@ -5,17 +5,22 @@
@section('content')
<div class="h-entry top-space">
<div class="h-cite u-like-of">
Liked <a class="u-url" href="{{ $like->url }}">a post</a> by
<span class="p-author h-card">
Liked <a class="u-url" href="{{ $like->url }}">a post</a>
@isset($like->author_name)
by <span class="p-author h-card">
@isset($like->author_url)
<a class="u-url p-name" href="{{ $like->author_url }}">{{ $like->author_name }}</a>
@else
<span class="p-name">{{ $like->author_name }}</span>
@endisset
</span>:
</span>
@endisset
<blockquote class="e-content">
{!! $like->content !!}
</blockquote>
</div>
</div>
<!-- POSSE to Twitter -->
<a href="https://brid.gy/publish/twitter"></a>
@stop

View file

@ -85,6 +85,16 @@ Route::group(['domain' => config('url.longurl')], function () {
Route::post('/merge', 'PlacesController@mergeStore');
Route::delete('/{id}', 'PlacesController@destroy');
});
//Likes
Route::group(['prefix' => 'likes'], function () {
Route::get('/', 'LikesController@index');
Route::get('/create', 'LikesController@create');
Route::post('/', 'LikesController@store');
Route::get('/{id}/edit', 'LikesController@edit');
Route::put('/{id}', 'LikesController@update');
Route::delete('/{id}', 'LikesController@destroy');
});
});
//Blog pages using ArticlesController

View file

@ -0,0 +1,76 @@
<?php
namespace Tests\Feature\Admin;
use Tests\TestCase;
use App\Models\Like;
use App\Jobs\ProcessLike;
use Illuminate\Support\Facades\Queue;
use Illuminate\Foundation\Testing\WithFaker;
use Illuminate\Foundation\Testing\DatabaseTransactions;
class LikesTest extends TestCase
{
use DatabaseTransactions;
public function test_index_page()
{
$response = $this->withSession(['loggedin' => true])
->get('/admin/likes');
$response->assertSeeText('Likes');
}
public function test_create_page()
{
$response = $this->withSession(['loggedin' => true])
->get('/admin/likes/create');
$response->assertSeeText('New Like');
}
public function test_create_new_like()
{
Queue::fake();
$this->withSession(['loggedin' => true])
->post('/admin/likes', [
'like_url' => 'https://example.com'
]);
$this->assertDatabaseHas('likes', [
'url' => 'https://example.com'
]);
Queue::assertPushed(ProcessLike::class);
}
public function test_see_edit_form()
{
$response = $this->withSession(['loggedin' => true])
->get('/admin/likes/1/edit');
$response->assertSee('Edit Like');
}
public function test_edit_like()
{
Queue::fake();
$this->withSession(['loggedin' => true])
->post('/admin/likes/1', [
'_method' => 'PUT',
'like_url' => 'https://example.com',
]);
$this->assertDatabaseHas('likes', [
'url' => 'https://example.com',
]);
Queue::assertPushed(ProcessLike::class);
}
public function test_delete_like()
{
$like = Like::find(1);
$url = $like->url;
$this->withSession(['loggedin' => true])
->post('/admin/likes/1', [
'_method' => 'DELETE',
]);
$this->assertDatabaseMissing('likes', [
'url' => $url,
]);
}
}

View file

@ -12,14 +12,6 @@ class HelpersTest extends TestCase
$this->assertEquals(normalize_url(normalize_url($input)), normalize_url($input));
}
/**
* @dataProvider urlProvider
*/
public function test_normalize_url($input, $output)
{
$this->assertEquals($output, normalize_url($input));
}
public function urlProvider()
{
return [
@ -27,9 +19,22 @@ class HelpersTest extends TestCase
['https://example.org:443/', 'https://example.org'],
['http://www.foo.bar/index.php/', 'http://www.foo.bar'],
['https://example.org/?foo=bar&baz=true', 'https://example.org?baz=true&foo=bar'],
[
'http://example.org/?ref_src=twcamp^share|twsrc^ios|twgr^software.studioh.Indigenous.share-micropub',
'http://example.org',
],
];
}
/**
* @dataProvider urlProvider
* @group temp
*/
public function test_normalize_url($input, $output)
{
$this->assertEquals($output, normalize_url($input));
}
public function test_pretty_print_json()
{
$json = <<<JSON