8
0
Fork 0

Improve confluence export

Migrate from Parsedown to Commonmark
Dieser Commit ist enthalten in:
Stéphane Goetz 2015-05-22 14:48:09 +02:00 committet von Stéphane Goetz
Ursprung fa798ff1e4
Commit 1fe3e62df3
14 geänderte Dateien mit 611 neuen und 169 gelöschten Zeilen

Datei anzeigen

@ -13,9 +13,9 @@
],
"require": {
"php": ">=5.4",
"erusev/parsedown": "~1.0",
"league/plates": "~3.1",
"guzzlehttp/guzzle": "~5.3"
"guzzlehttp/guzzle": "~5.3",
"league/commonmark": "0.8.*"
},
"autoload": {
"psr-4": {"Todaymade\\Daux\\": "libs/"}

102
composer.lock generiert
Datei anzeigen

@ -4,47 +4,8 @@
"Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"This file is @generated automatically"
],
"hash": "82c1c29dbd870c4ee2ea79c0561ea5d8",
"hash": "a7e29fdc079b4e2a588148bff949237a",
"packages": [
{
"name": "erusev/parsedown",
"version": "1.0.0",
"source": {
"type": "git",
"url": "https://github.com/erusev/parsedown.git",
"reference": "2da10d277b086372f17b96df6cdc903829e1dde0"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/erusev/parsedown/zipball/2da10d277b086372f17b96df6cdc903829e1dde0",
"reference": "2da10d277b086372f17b96df6cdc903829e1dde0",
"shasum": ""
},
"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": "2014-05-14 10:14:49"
},
{
"name": "guzzlehttp/guzzle",
"version": "5.3.0",
@ -204,6 +165,67 @@
],
"time": "2014-10-12 19:18:40"
},
{
"name": "league/commonmark",
"version": "0.8.0",
"source": {
"type": "git",
"url": "https://github.com/thephpleague/commonmark.git",
"reference": "91696c88df298f75fdd2075e4bb19c6dbd7338ca"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/thephpleague/commonmark/zipball/91696c88df298f75fdd2075e4bb19c6dbd7338ca",
"reference": "91696c88df298f75fdd2075e4bb19c6dbd7338ca",
"shasum": ""
},
"require": {
"ext-mbstring": "*",
"php": ">=5.4.8"
},
"replace": {
"colinodell/commonmark-php": "*"
},
"require-dev": {
"erusev/parsedown": "~1.0",
"jgm/commonmark": "0.19",
"michelf/php-markdown": "~1.4",
"phpunit/phpunit": "~4.3",
"phpunit/phpunit-mock-objects": "2.3.0",
"symfony/finder": "~2.3"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "0.8-dev"
}
},
"autoload": {
"psr-4": {
"League\\CommonMark\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Colin O'Dell",
"email": "colinodell@gmail.com",
"homepage": "http://www.colinodell.com",
"role": "Lead Developer"
}
],
"description": "Markdown parser for PHP based on the CommonMark spec",
"homepage": "https://github.com/thephpleague/commonmark",
"keywords": [
"commonmark",
"markdown",
"parser"
],
"time": "2015-04-29 18:01:46"
},
{
"name": "league/plates",
"version": "3.1.0",

Datei anzeigen

@ -84,7 +84,7 @@ class Daux
// Read command line overrides
$config_file = $this->local_base . DS . $override_file;
if (file_exists($config_file)) {
if (!is_null($override_file) && file_exists($config_file)) {
$config = json_decode(file_get_contents($config_file), true);
if (!isset($config)) {
throw new Exception('The local config file is missing. Check path : ' . $config_file);

Datei anzeigen

@ -50,12 +50,15 @@ class DauxHelper
return $theme;
}
public static function getCleanPath($path) {
public static function getCleanPath($path)
{
$path = str_replace(array('/', '\\'), DIRECTORY_SEPARATOR, $path);
$parts = array_filter(explode(DIRECTORY_SEPARATOR, $path), 'strlen');
$absolutes = array();
foreach ($parts as $part) {
if ('.' == $part) continue;
if ('.' == $part) {
continue;
}
if ('..' == $part) {
array_pop($absolutes);
} else {

Datei anzeigen

@ -1,5 +1,6 @@
<?php namespace Todaymade\Daux\Format\Base;
use League\CommonMark\CommonMarkConverter;
use Todaymade\Daux\Tree\Content;
abstract class MarkdownPage extends SimplePage
@ -29,9 +30,19 @@ abstract class MarkdownPage extends SimplePage
$this->params = $params;
}
protected function getMarkdownConverter()
{
return new CommonMarkConverter();
}
protected function convertPage($content)
{
return $this->getMarkdownConverter()->convertToHtml($content);
}
protected function generatePage()
{
return (new \Parsedown())->text($this->content);
return $this->convertPage($this->content);
}
public static function fromFile(Content $file, $params)

Datei anzeigen

@ -1,8 +1,12 @@
<?php namespace Todaymade\Daux\Format\Confluence;
use GuzzleHttp\Client;
use GuzzleHttp\Exception\BadResponseException;
use GuzzleHttp\Exception\ParseException;
use GuzzleHttp\Exception\TransferException;
class Api {
class Api
{
protected $base_url;
protected $user;
@ -10,28 +14,82 @@ class Api {
protected $space;
public function __construct($base_url, $user, $pass, $space_id) {
public function __construct($base_url, $user, $pass)
{
$this->base_url = $base_url;
$this->user = $user;
$this->pass = $pass;
$this->setSpace($space_id);
}
public function setSpace($space_id) {
public function setSpace($space_id)
{
$this->space = $space_id;
}
protected function getClient()
{
$options = [
'base_url' => $this->base_url . 'rest/api/',
'defaults' => [
'auth' => [$this->user, $this->pass]
]
];
return new Client($options);
}
/**
* The standard error message from guzzle is quite poor in informations,
* this will give little bit more sense to it and return it
*
* @param BadResponseException $e
* @return BadResponseException
*/
protected function handleError(BadResponseException $e)
{
$request = $e->getRequest();
$response = $e->getResponse();
$level = floor($response->getStatusCode() / 100);
if ($level == '4') {
$label = 'Client error response';
} elseif ($level == '5') {
$label = 'Server error response';
} else {
$label = 'Unsuccessful response';
}
$message = $label .
' [url] ' . $request->getUrl() .
' [status code] ' . $response->getStatusCode() .
' [message] ';
try {
$message .= $response->json()['message'];
} catch (ParseException $e) {
$message .= (string) $response->getBody();
}
return new BadResponseException($message, $request, $response, $e->getPrevious());
}
/**
* /rest/api/content/{id}/child/{type}
*
* @param $rootPage
* @return mixed
*/
public function getHierarchy($rootPage) {
$hiera = $this->getClient()->get("content/$rootPage/child/page?expand=version,body.storage")->json();
public function getHierarchy($rootPage)
{
try {
$hierarchy = $this->getClient()->get("content/$rootPage/child/page?expand=version,body.storage")->json();
} catch (BadResponseException $e) {
throw $this->handleError($e);
}
$children = [];
foreach($hiera['results'] as $result) {
foreach ($hierarchy['results'] as $result) {
$children[$result['title']] = [
"id" => $result['id'],
"title" => $result['title'],
@ -44,8 +102,8 @@ class Api {
return $children;
}
public function createPage($parent_id, $title, $content) {
public function createPage($parent_id, $title, $content)
{
$body = [
'type' => 'page',
'space' => ['key' => $this->space],
@ -54,12 +112,17 @@ class Api {
'body' => ['storage' => ['value' => $content, 'representation' => 'storage']]
];
$response = $this->getClient()->post('content', [ 'json' => $body ])->json();
try {
$response = $this->getClient()->post('content', [ 'json' => $body ])->json();
} catch (BadResponseException $e) {
throw $this->handleError($e);
}
return $response['id'];
}
public function updatePage($parent_id, $page_id, $newVersion, $title, $content) {
public function updatePage($parent_id, $page_id, $newVersion, $title, $content)
{
$body = [
'type' => 'page',
'space' => ['key' => $this->space],
@ -69,22 +132,45 @@ class Api {
'body' => ['storage' => ['value' => $content, 'representation' => 'storage']]
];
$this->getClient()->put("content/$page_id", [ 'json' => $body ])->json();
try {
$this->getClient()->put("content/$page_id", ['json' => $body])->json();
} catch (BadResponseException $e) {
throw $this->handleError($e);
}
}
public function deletePage($page_id) {
return $this->getClient()->delete('content/' . $page_id)->json();
public function deletePage($page_id)
{
try {
return $this->getClient()->delete('content/' . $page_id)->json();
} catch (BadResponseException $e) {
throw $this->handleError($e);
}
}
protected function getClient() {
public function uploadAttachment($id, $attachment)
{
//get if attachment is uploaded
try {
$result = $this->getClient()->get("content/$id/child/attachment?filename=$attachment[filename]")->json();
} catch (BadResponseException $e) {
throw $this->handleError($e);
}
$options = [
'base_url' => $this->base_url . 'rest/api/',
'defaults' => [
'auth' => [$this->user, $this->pass]
]
];
$url = "content/$id/child/attachment" . (count($result['results'])? "/{$result['results'][0]['id']}/data" : "");
return new Client($options);
try {
$this->getClient()->post(
$url,
[
'body' => ['file' => fopen($attachment['file']->getPath(), 'r')] ,
'headers' => ['X-Atlassian-Token' => 'nocheck'],
]
);
} catch (BadResponseException $e) {
throw $this->handleError($e);
}
//FIXME :: When doing an update, Confluence does a null pointer exception
}
}

Datei anzeigen

@ -0,0 +1,26 @@
<?php namespace Todaymade\Daux\Format\Confluence;
use League\CommonMark\DocParser;
use League\CommonMark\Environment;
use League\CommonMark\HtmlRenderer;
class CommonMarkConverter extends \League\CommonMark\CommonMarkConverter
{
/**
* Create a new commonmark converter instance.
*
* @param array $config
*/
public function __construct(array $config = array())
{
$environment = Environment::createCommonMarkEnvironment();
$environment->mergeConfig($config);
//Add code renderer
$environment->addBlockRenderer('FencedCode', new FencedCodeRenderer());
$environment->addBlockRenderer('IndentedCode', new IndentedCodeRenderer());
$this->docParser = new DocParser($environment);
$this->htmlRenderer = new HtmlRenderer($environment);
}
}

Datei anzeigen

@ -0,0 +1,85 @@
<?php namespace Todaymade\Daux\Format\Confluence;
use League\CommonMark\Block\Element\AbstractBlock;
use League\CommonMark\Block\Element\FencedCode;
use League\CommonMark\Block\Renderer\BlockRendererInterface;
use League\CommonMark\HtmlElement;
use League\CommonMark\HtmlRendererInterface;
class FencedCodeRenderer implements BlockRendererInterface
{
protected $supported_languages = [
'actionscript3',
'bash',
'csharp',
'coldfusion',
'cpp',
'css',
'delphi',
'diff',
'erlang',
'groovy',
'html/xml',
'java',
'javafx',
'javascript',
'none',
'perl',
'php',
'powershell',
'python',
'ruby',
'scala',
'sql',
'vb'
];
protected $known_conversions = ['html' => 'html/xml', 'xml' => 'html/xml', 'js' => 'javascript'];
/**
* @param AbstractBlock $block
* @param HtmlRendererInterface $htmlRenderer
* @param bool $inTightList
*
* @return HtmlElement|string
*/
public function render(AbstractBlock $block, HtmlRendererInterface $htmlRenderer, $inTightList = false)
{
if (!($block instanceof FencedCode)) {
throw new \InvalidArgumentException('Incompatible block type: ' . get_class($block));
}
$content = [];
if ($language = $this->getLanguage($block->getInfoWords(), $htmlRenderer)) {
$content[] = new HtmlElement('ac:parameter', ['ac:name' => 'language'], $language);
}
$content[] = new HtmlElement('ac:plain-text-body', [], '<![CDATA[' . $block->getStringContent() . ']]>');
return new HtmlElement(
'ac:structured-macro',
['ac:name' => 'code'],
$content
);
}
public function getLanguage($infoWords, HtmlRendererInterface $htmlRenderer)
{
if (count($infoWords) === 0 || strlen($infoWords[0]) === 0) {
return false;
}
$language = $htmlRenderer->escape($infoWords[0], true);
if (array_key_exists($language, $this->known_conversions)) {
$language = $this->known_conversions[$language];
}
if (in_array($language, $this->supported_languages)) {
return $language;
}
return false;
}
}

Datei anzeigen

@ -1,6 +1,5 @@
<?php namespace Todaymade\Daux\Format\Confluence;
use GuzzleHttp\Exception\ClientException;
use Todaymade\Daux\Daux;
use Todaymade\Daux\Tree\Content;
use Todaymade\Daux\Tree\Directory;
@ -8,112 +7,30 @@ use Todaymade\Daux\Tree\Entry;
class Generator
{
/**
* @var Api
*/
protected $client;
/**
* @var string
*/
protected $prefix;
public function generate(Daux $daux)
{
$confluence = $daux->getParams()['confluence'];
$this->prefix = trim($confluence['prefix']) . " ";
$main_title = $this->prefix . $daux->getParams()['title'];
$params = $daux->getParams();
echo "Generating Tree...\n";
$tree = $this->generateRecursive($daux->tree, $params);
$tree['title'] = $main_title;
$tree['title'] = $this->prefix . $daux->getParams()['title'];
echo "Getting already published pages...\n";
$this->client = new Api($confluence['base_url'], $confluence['user'], $confluence['pass'], $confluence['space_id']);
$all_published = $this->client->getHierarchy($confluence['ancestor_id']);
echo "Finding Root Page...\n";
$published = [];
foreach ($all_published as $page) {
if ($page['title'] == $main_title) {
$published = $page;
break;
}
}
echo "Create placeholder pages...\n";
$published = $this->createRecursive($confluence['ancestor_id'], $tree, $published);
echo "Publishing updates...\n";
$this->updateRecursive($confluence['ancestor_id'], $tree, $published);
echo "Start Publishing...\n";
$publisher = new Publisher($confluence);
$publisher->publish($tree);
echo "Done !\n";
}
private function createRecursive($parent_id, $entry, $published)
{
//TODO :: remove deleted pages
if (!array_key_exists('id', $published)) {
if (array_key_exists('page', $entry)) {
echo "Creating: " . $entry['file']->getUrl() . "\n";
$published['version'] = 1;
$published['id'] = $this->client->createPage($parent_id, $entry['title'], "The content will come very soon !");
} else {
echo "Creating Placeholder page: " . $entry['title'] . "\n";
$published['version'] = 1;
$published['id'] = $this->client->createPage($parent_id, $entry['title'], "");
}
}
if (array_key_exists('children', $entry)) {
foreach($entry['children'] as $child) {
$pub = [];
if (array_key_exists('children', $published) && array_key_exists($child['title'], $published['children'])) {
$pub = $published['children'][$child['title']];
}
$published['children'][$child['title']] = $this->createRecursive($published['id'], $child, $pub);
}
}
return $published;
}
private function updateRecursive($parent_id, $entry, $published)
{
if (array_key_exists('id', $published) && array_key_exists('page', $entry)) {
echo "Updating: " . $entry['file']->getUrl() . "\n";
try {
$this->client->updatePage(
$parent_id,
$published['id'],
$published['version'] + 1,
$entry['title'],
$entry['page']->getContent()
);
} catch (ClientException $e) {
echo "-> Failed with message: " . $e->getResponse()->json()['message'] . "\n";
}
}
if (array_key_exists('children', $entry)) {
foreach($entry['children'] as $child) {
$pub = [];
if (array_key_exists('children', $published) && array_key_exists($child['title'], $published['children'])) {
$pub = $published['children'][$child['title']];
}
$this->updateRecursive($published['id'], $child, $pub);
}
}
}
private function generateRecursive(Entry $tree, array $params, $base_url = '')
{
$final = ['title' => $this->prefix . $tree->getTitle()];
@ -125,9 +42,12 @@ class Generator
}
foreach ($tree->value as $key => $node) {
if ($node instanceof Directory) {
$final['children'][$this->prefix . $node->getTitle()] = $this->generateRecursive($node, $params, '../' . $base_url);
} else if ($node instanceof Content) {
$final['children'][$this->prefix . $node->getTitle()] = $this->generateRecursive(
$node,
$params,
'../' . $base_url
);
} elseif ($node instanceof Content) {
$params['request'] = $node->getUrl();
$params['file_uri'] = $node->getName();
@ -137,6 +57,10 @@ class Generator
'page' => MarkdownPage::fromFile($node, $params),
];
// As the page is lazily generated
// We do it now to fail fast in case of problem
$data['page']->getContent();
if ($key == 'index.html') {
$final['title'] = $this->prefix . $tree->getTitle();
$final['file'] = $node;

Datei anzeigen

@ -0,0 +1,30 @@
<?php namespace Todaymade\Daux\Format\Confluence;
use League\CommonMark\Block\Element\AbstractBlock;
use League\CommonMark\Block\Element\IndentedCode;
use League\CommonMark\Block\Renderer\BlockRendererInterface;
use League\CommonMark\HtmlElement;
use League\CommonMark\HtmlRendererInterface;
class IndentedCodeRenderer implements BlockRendererInterface
{
/**
* @param AbstractBlock $block
* @param HtmlRendererInterface $htmlRenderer
* @param bool $inTightList
*
* @return HtmlElement
*/
public function render(AbstractBlock $block, HtmlRendererInterface $htmlRenderer, $inTightList = false)
{
if (!($block instanceof IndentedCode)) {
throw new \InvalidArgumentException('Incompatible block type: ' . get_class($block));
}
return new HtmlElement(
'ac:structured-macro',
['ac:name' => 'code'],
new HtmlElement('ac:plain-text-body', [], '<![CDATA['.$block->getStringContent().']]>')
);
}
}

Datei anzeigen

@ -1,18 +1,32 @@
<?php namespace Todaymade\Daux\Format\Confluence;
use DOMDocument;
use Todaymade\Daux\DauxHelper;
class MarkdownPage extends \Todaymade\Daux\Format\Base\MarkdownPage
{
public $attachments = [];
protected function getMarkdownConverter()
{
return new CommonMarkConverter();
}
protected function generatePage()
{
$page = parent::generatePage();
//Embed images
// We do it after generation so we can catch the images that were in html already
$page = preg_replace_callback(
"/<img\\s+[^>]*src=['\"]([^\"]*)['\"][^>]*>/",
function ($matches) {
return str_replace($matches[1], $this->findImage($matches[1]), $matches[0]);
if ($result = $this->findImage($matches[1], $matches[0])) {
return $result;
}
return $matches[0];
},
$page
);
@ -20,7 +34,7 @@ class MarkdownPage extends \Todaymade\Daux\Format\Base\MarkdownPage
return $page;
}
private function findImage($src)
private function findImage($src, $tag)
{
//for protocol relative or http requests : keep the original one
if (substr($src, 0, strlen("http")) === "http" || substr($src, 0, strlen("//")) === "//") {
@ -35,16 +49,46 @@ class MarkdownPage extends \Todaymade\Daux\Format\Base\MarkdownPage
if ($file === false) {
return $src;
return false;
}
$encoded = base64_encode(file_get_contents($file->getPath()));
$extension = pathinfo($file->getPath(), PATHINFO_EXTENSION);
$filename = basename($file->getPath());
if (!in_array($extension, ['jpg', 'jpeg', 'png', 'gif'])) {
return $src;
//Add the attachment for later upload
$this->attachments[] = ['filename' => $filename, 'file' => $file];
return $this->createImageTag($filename, $this->getAttributes($tag));
}
private function getAttributes($tag)
{
$dom = new DOMDocument();
$dom->loadHTML($tag);
$img = $dom->getElementsByTagName('img')[0];
$attributes = ['align', 'class', 'title', 'style', 'alt', 'height', 'width'];
$used = [];
foreach ($attributes as $attr) {
if ($img->attributes->getNamedItem($attr)) {
$used[$attr] = $img->attributes->getNamedItem($attr)->value;
}
}
return "data:image/$extension;base64,$encoded";
return $used;
}
private function createImageTag($filename, $attributes)
{
$img = "<ac:image";
foreach ($attributes as $name => $value) {
$img .= ' ac:' . $name.'="'.htmlentities($value, ENT_QUOTES, 'UTF-8', false).'"';
}
$img .= "><ri:attachment ri:filename=\"$filename\" /></ac:image>";
return $img;
}
}

Datei anzeigen

@ -0,0 +1,212 @@
<?php namespace Todaymade\Daux\Format\Confluence;
use GuzzleHttp\Exception\BadResponseException;
use GuzzleHttp\Exception\ParseException;
class Publisher
{
/**
* @var Api
*/
protected $client;
/**
* @var array
*/
protected $confluence;
/**
* @var string
*/
protected $previous_title;
public function __construct($confluence)
{
$this->confluence = $confluence;
$this->client = new Api($confluence['base_url'], $confluence['user'], $confluence['pass']);
$this->client->setSpace($confluence['space_id']);
}
public function publish(array $tree)
{
echo "Getting already published pages...\n";
$all_published = $this->client->getHierarchy($this->confluence['ancestor_id']);
echo "Finding Root Page...\n";
$published = [];
foreach ($all_published as $page) {
if ($page['title'] == $tree['title']) {
$published = $page;
break;
}
}
echo "Create placeholder pages...\n";
$published = $this->createRecursive($this->confluence['ancestor_id'], $tree, $published);
echo "Publishing updates...\n";
$this->updateRecursive($this->confluence['ancestor_id'], $tree, $published);
}
protected function niceTitle($title)
{
if ($title == "index.html") {
return "Homepage";
}
return rtrim(strtr($title, ['index.html' => '', '.html' => '']), "/");
}
protected function createPage($parent_id, $entry, $published)
{
if ($this->previous_title != "Creating") {
$this->previous_title = "Creating";
echo "Creating Pages...\n";
}
echo "- " . $this->niceTitle($entry['file']->getUrl());
$published['version'] = 1;
$published['id'] = $this->client->createPage($parent_id, $entry['title'], "The content will come very soon !");
echo "\n";
return $published;
}
protected function createPlaceholderPage($parent_id, $entry, $published)
{
if ($this->previous_title != "Creating Placeholder") {
$this->previous_title = "Creating Placeholder";
echo "Creating Placeholder Pages...\n";
}
echo "- " . $entry['title'];
$published['version'] = 1;
$published['id'] = $this->client->createPage($parent_id, $entry['title'], "");
echo "\n";
return $published;
}
protected function recursiveWithCallback($parent_id, $entry, $published, $callback)
{
$published = $callback($parent_id, $entry, $published);
if (array_key_exists('children', $entry)) {
foreach ($entry['children'] as $child) {
$pub = [];
if (isset($published['children']) && array_key_exists($child['title'], $published['children'])) {
$pub = $published['children'][$child['title']];
}
$published['children'][$child['title']] = $this->recursiveWithCallback(
$published['id'],
$child,
$pub,
$callback
);
}
}
return $published;
}
protected function createRecursive($parent_id, $entry, $published)
{
$callback = function ($parent_id, $entry, $published) {
//TODO :: remove deleted pages
// nothing to do if the ID already exists
if (array_key_exists('id', $published)) {
return $published;
}
if (array_key_exists('page', $entry)) {
return $this->createPage($parent_id, $entry, $published);
}
// If we have no $entry['page'] it means the page
// doesn't exist, but to respect the hierarchy,
// we need a blank page there
return $this->createPlaceholderPage($parent_id, $entry, $published);
};
return $this->recursiveWithCallback($parent_id, $entry, $published, $callback);
}
protected function updateRecursive($parent_id, $entry, $published)
{
$callback = function ($parent_id, $entry, $published) {
if (array_key_exists('id', $published) && array_key_exists('page', $entry)) {
$this->updatePage($parent_id, $entry, $published);
}
return $published;
};
return $this->recursiveWithCallback($parent_id, $entry, $published, $callback);
}
protected function shouldUpdate($local, $published)
{
if (!array_key_exists('content', $published)) {
return true;
}
$trimmed_local = trim($local);
$trimmed_distant = trim($published['content']);
if ($trimmed_local == $trimmed_distant) {
return false;
}
similar_text($trimmed_local, $trimmed_distant, $percent);
// I consider that if the files are 98% identical you
// don't need to update. This will work for false positives.
// But sadly will miss if it's just a typo update
if ($percent >= 98) {
return false;
}
return true;
}
protected function updatePage($parent_id, $entry, $published)
{
if ($this->previous_title != "Updating") {
$this->previous_title = "Updating";
echo "Updating Pages...\n";
}
echo "- " . $this->niceTitle($entry['file']->getUrl());
try {
if ($this->shouldUpdate($entry['page']->getContent(), $published)) {
$this->client->updatePage(
$parent_id,
$published['id'],
$published['version'] + 1,
$entry['title'],
$entry['page']->getContent()
);
echo "\n";
} else {
echo " √ (No update needed)\n";
}
if (count($entry['page']->attachments)) {
foreach ($entry['page']->attachments as $attachment) {
echo " With attachment: $attachment[filename]";
$this->client->uploadAttachment($published['id'], $attachment);
echo "\n";
}
}
} catch (BadResponseException $e) {
echo " X Failed with message: " . $e->getMessage() . "\n";
}
}
}

Datei anzeigen

@ -69,7 +69,7 @@ class MarkdownPage extends \Todaymade\Daux\Format\Base\MarkdownPage
'modified_time' => filemtime($this->file->getPath()),
'markdown' => $this->content,
'request' => $params['request'],
'content' => (new \Parsedown())->text($this->content),
'content' => $this->convertPage($this->content),
'breadcrumbs' => $params['breadcrumbs']
];

Datei anzeigen

@ -254,8 +254,7 @@ class Getopt
$long = [];
$short = '';
foreach ($this->rules as $rule) {
foreach($rule['alias'] as $alias) {
foreach ($rule['alias'] as $alias) {
$prepared = $alias;
if ($rule['param'] == 'optional') {
$prepared .= '::';