Browse Source

:tada: First commit

master
Clement Desmidt 2 years ago
commit
111efb3ddb
2 changed files with 758 additions and 0 deletions
  1. 591
    0
      HTML-To-Markdown.php
  2. 167
    0
      export.php

+ 591
- 0
HTML-To-Markdown.php View File

@@ -0,0 +1,591 @@
1
+<?php
2
+/**
3
+ * Class HTML_To_Markdown
4
+ *
5
+ * A helper class to convert HTML to Markdown.
6
+ *
7
+ * @version 2.1.1
8
+ * @author Nick Cernis <nick@cern.is>
9
+ * @link https://github.com/nickcernis/html2markdown/ Latest version on GitHub.
10
+ * @link http://twitter.com/nickcernis Nick on twitter.
11
+ * @license http://www.opensource.org/licenses/mit-license.php MIT
12
+ */
13
+class HTML_To_Markdown {
14
+	/**
15
+	 * @var DOMDocument The root of the document tree that holds our HTML.
16
+	 */
17
+	private $document;
18
+
19
+	/**
20
+	 * @var string|boolean The Markdown version of the original HTML, or false if conversion failed
21
+	 */
22
+	private $output;
23
+
24
+	/**
25
+	 * @var array Class-wide options users can override.
26
+	 */
27
+	private $options = array(
28
+		'header_style' => 'atx', // Set to "atx" to output H1 and H2 headers as # Header1 and ## Header2
29
+		'suppress_errors' => true, // Set to false to show warnings when loading malformed HTML
30
+		'strip_tags' => false, // Set to true to strip tags that don't have markdown equivalents. N.B. Strips tags, not their content. Useful to clean MS Word HTML output.
31
+		'bold_style' => '**', // Set to '__' if you prefer the underlined style
32
+		'italic_style' => '*', // Set to '_' if you prefer the underlined style
33
+	);
34
+
35
+
36
+	/**
37
+	 * Constructor
38
+	 *
39
+	 * Set up a new DOMDocument from the supplied HTML, convert it to Markdown, and store it in $this->$output.
40
+	 *
41
+	 * @param string $html The HTML to convert to Markdown.
42
+	 * @param array $overrides [optional] List of style and error display overrides.
43
+	 */
44
+	public function __construct( $html = null, $overrides = null ) {
45
+		if ( $overrides ) {
46
+			$this->options = array_merge( $this->options, $overrides );
47
+		}
48
+
49
+		if ( $html ) {
50
+			$this->convert( $html );
51
+
52
+		}
53
+	}
54
+
55
+
56
+	/**
57
+	 * Setter for conversion options
58
+	 *
59
+	 * @param $name
60
+	 * @param $value
61
+	 */
62
+	public function set_option( $name, $value ) {
63
+		$this->options[$name] = $value;
64
+	}
65
+
66
+
67
+	/**
68
+	 * Convert
69
+	 *
70
+	 * Loads HTML and passes to get_markdown()
71
+	 *
72
+	 * @param $html
73
+	 * @return string The Markdown version of the html
74
+	 */
75
+	public function convert( $html )
76
+	{
77
+		$html = preg_replace( '~>\s+<~', '><', $html ); // Strip white space between tags to prevent creation of empty #text nodes
78
+
79
+		$this->document = new DOMDocument();
80
+
81
+		if ( $this->options['suppress_errors'] ) {
82
+			libxml_use_internal_errors( true ); // Suppress conversion errors (from http://bit.ly/pCCRSX )
83
+		}
84
+
85
+		$this->document->loadHTML( '<?xml encoding="UTF-8">' . $html ); // Hack to load utf-8 HTML (from http://bit.ly/pVDyCt )
86
+		$this->document->encoding = 'UTF-8';
87
+
88
+		if ( $this->options['suppress_errors'] ) {
89
+			libxml_clear_errors();
90
+		}
91
+
92
+		return $this->get_markdown( $html );
93
+	}
94
+
95
+
96
+	/**
97
+	 * Is Child Of?
98
+	 *
99
+	 * Is the node a child of the given parent tag?
100
+	 *
101
+	 * @param $parent_name string The name of the parent node to search for (e.g. 'code')
102
+	 * @param $node
103
+	 * @return bool
104
+	 */
105
+	private static function is_child_of( $parent_name, $node ) {
106
+		for ( $p = $node->parentNode; $p != false; $p = $p->parentNode ) {
107
+			if ( is_null( $p ) ) {
108
+				return false;
109
+			}
110
+
111
+			if ( $p->nodeName == $parent_name ) {
112
+				return true;
113
+			}
114
+		}
115
+		return false;
116
+	}
117
+
118
+
119
+	/**
120
+	 * Convert Children
121
+	 *
122
+	 * Recursive function to drill into the DOM and convert each node into Markdown from the inside out.
123
+	 *
124
+	 * Finds children of each node and convert those to #text nodes containing their Markdown equivalent,
125
+	 * starting with the innermost element and working up to the outermost element.
126
+	 *
127
+	 * @param $node
128
+	 */
129
+	private function convert_children( $node ) {
130
+		// Don't convert HTML code inside <code> blocks to Markdown - that should stay as HTML
131
+		if ( self::is_child_of( 'code', $node ) ) {
132
+			return;
133
+		}
134
+
135
+		// If the node has children, convert those to Markdown first
136
+		if ( $node->hasChildNodes() ) {
137
+			$length = $node->childNodes->length;
138
+
139
+			for ( $i = 0; $i < $length; $i++ ) {
140
+				$child = $node->childNodes->item( $i );
141
+				$this->convert_children( $child );
142
+			}
143
+		}
144
+
145
+		// Now that child nodes have been converted, convert the original node
146
+		$this->convert_to_markdown( $node );
147
+	}
148
+
149
+
150
+	/**
151
+	 * Get Markdown
152
+	 *
153
+	 * Sends the body node to convert_children() to change inner nodes to Markdown #text nodes, then saves and
154
+	 * returns the resulting converted document as a string in Markdown format.
155
+	 *
156
+	 * @return string|boolean The converted HTML as Markdown, or false if conversion failed
157
+	 */
158
+	private function get_markdown()
159
+	{
160
+		// Use the body tag as our root element
161
+		$body = $this->document->getElementsByTagName( 'body' )->item( 0 );
162
+
163
+		// Try the head tag if there's no body tag (e.g. the user's passed a single <script> tag for conversion)
164
+		if ( ! $body ) {
165
+			$body = $this->document->getElementsByTagName( 'head' )->item( 0 );
166
+		}
167
+
168
+		if ( ! $body ) {
169
+			return false;
170
+		}
171
+
172
+		// Convert all children of the body element. The DOMDocument stored in $this->doc will
173
+		// then consist of #text nodes, each containing a Markdown version of the original node
174
+		// that it replaced.
175
+		$this->convert_children( $body );
176
+
177
+		// Sanitize and return the body contents as a string.
178
+		$markdown = $this->document->saveHTML(); // stores the DOMDocument as a string
179
+		$markdown = html_entity_decode( $markdown, ENT_QUOTES, 'UTF-8' );
180
+		$markdown = html_entity_decode( $markdown, ENT_QUOTES, 'UTF-8' ); // Double decode to cover cases like &amp;nbsp; http://www.php.net/manual/en/function.htmlentities.php#99984
181
+		$markdown = preg_replace( '/<!DOCTYPE [^>]+>/', '', $markdown ); // Strip doctype declaration
182
+		$unwanted = array( '<html>', '</html>', '<body>', '</body>', '<head>', '</head>', '<?xml encoding="UTF-8">', '&#xD;' );
183
+		$markdown = str_replace( $unwanted, '', $markdown ); // Strip unwanted tags
184
+		$markdown = trim( $markdown, '\n\r\0\x0B' );
185
+
186
+		$this->output = $markdown;
187
+
188
+		return $markdown;
189
+	}
190
+
191
+
192
+	/**
193
+	 * Convert to Markdown
194
+	 *
195
+	 * Converts an individual node into a #text node containing a string of its Markdown equivalent.
196
+	 *
197
+	 * Example: An <h3> node with text content of "Title" becomes a text node with content of "### Title"
198
+	 *
199
+	 * @param $node
200
+	 */
201
+	private function convert_to_markdown( $node ) {
202
+		$tag = $node->nodeName; // the type of element, e.g. h1
203
+		$value = $node->nodeValue; // the value of that element, e.g. The Title
204
+
205
+		switch ( $tag ) {
206
+			case 'p':
207
+			case 'pre':
208
+				$markdown = ( trim( $value ) ) ? rtrim( $value ) . PHP_EOL . PHP_EOL : '';
209
+				break;
210
+			case 'h1':
211
+			case 'h2':
212
+				$markdown = $this->convert_header( $tag, $node );
213
+				break;
214
+			case 'h3':
215
+				$markdown = '### ' . $value . PHP_EOL . PHP_EOL;
216
+				break;
217
+			case 'h4':
218
+				$markdown = '#### ' . $value . PHP_EOL . PHP_EOL;
219
+				break;
220
+			case 'h5':
221
+				$markdown = '##### ' . $value . PHP_EOL . PHP_EOL;
222
+				break;
223
+			case 'h6':
224
+				$markdown = '###### ' . $value . PHP_EOL . PHP_EOL;
225
+				break;
226
+			case 'em':
227
+			case 'i':
228
+			case 'strong':
229
+			case 'b':
230
+				$markdown = $this->convert_emphasis( $tag, $value );
231
+				break;
232
+			case 'hr':
233
+				$markdown = '- - - - - -' . PHP_EOL . PHP_EOL;
234
+				break;
235
+			case 'br':
236
+				$markdown = '  ' . PHP_EOL;
237
+				break;
238
+			case 'blockquote':
239
+				$markdown = $this->convert_blockquote( $node );
240
+				break;
241
+			case 'code':
242
+				$markdown = $this->convert_code( $node );
243
+				break;
244
+			case 'ol':
245
+			case 'ul':
246
+				$markdown = $value . PHP_EOL;
247
+				break;
248
+			case 'li':
249
+				$markdown = $this->convert_list( $node );
250
+				break;
251
+			case 'img':
252
+				$markdown = $this->convert_image( $node );
253
+				break;
254
+			case 'a':
255
+				$markdown = $this->convert_anchor( $node );
256
+				break;
257
+			case '#text':
258
+				$markdown = preg_replace( '~\s+~', ' ', $value );
259
+				break;
260
+			case '#comment':
261
+				$markdown = '';
262
+				break;
263
+			default:
264
+				// If strip_tags is false (the default), preserve tags that don't have Markdown equivalents,
265
+				// such as <span> and #text nodes on their own. C14N() canonicalizes the node to a string.
266
+				// See: http://www.php.net/manual/en/domnode.c14n.php
267
+				$markdown = ($this->options['strip_tags']) ? $value : html_entity_decode( $node->C14N() );
268
+		}
269
+
270
+		// Create a DOM text node containing the Markdown equivalent of the original node
271
+		$markdown_node = $this->document->createTextNode( $markdown );
272
+
273
+		// Replace the old $node e.g. "<h3>Title</h3>" with the new $markdown_node e.g. "### Title"
274
+		$node->parentNode->replaceChild( $markdown_node, $node );
275
+	}
276
+
277
+
278
+	/**
279
+	 * Convert Header
280
+	 *
281
+	 * Converts h1 and h2 headers to Markdown-style headers in setext style,
282
+	 * matching the number of underscores with the length of the title.
283
+	 *
284
+	 * e.g.	 Header 1	Header Two
285
+	 *		  ========	----------
286
+	 *
287
+	 * Returns atx headers instead if $this->options['header_style'] is "atx"
288
+	 *
289
+	 * e.g.	# Header 1   ## Header Two
290
+	 *
291
+	 * @param string $level The header level, including the "h". e.g. h1
292
+	 * @param string $node The node to convert.
293
+	 * @return string The Markdown version of the header.
294
+	 */
295
+	private function convert_header( $level, $node ) {
296
+		$content = $node->nodeValue;
297
+
298
+		if ( ! $this->is_child_of( 'blockquote', $node ) && $this->options['header_style'] == 'setext' ) {
299
+			$length = ( function_exists( 'mb_strlen' ) ) ? mb_strlen( $content, 'utf-8' ) : strlen( $content );
300
+			$underline = ($level == 'h1' ) ? '=' : '-';
301
+			$markdown = PHP_EOL . $content . PHP_EOL . str_repeat( $underline, $length ) . PHP_EOL . PHP_EOL; // setext style
302
+		} else {
303
+			$prefix = ( $level == 'h1' ) ? '# ' : '## ';
304
+			$markdown = PHP_EOL . $prefix . $content . PHP_EOL . PHP_EOL; // atx style
305
+		}
306
+
307
+		return $markdown;
308
+	}
309
+
310
+
311
+	/**
312
+	 * Converts inline styles
313
+	 * This function is used to render strong and em tags
314
+	 *
315
+	 * eg <strong>bold text</strong> becomes **bold text** or __bold text__
316
+	 *
317
+	 * @param string $tag
318
+	 * @param string $value
319
+	 * @return string
320
+	 */
321
+	private function convert_emphasis( $tag, $value ) {
322
+		if ( $tag == 'i' || $tag == 'em' ) {
323
+			$markdown = $this->options['italic_style'] . $value . $this->options['italic_style'];
324
+		} else {
325
+			$markdown = $this->options['bold_style'] . $value . $this->options['bold_style'];
326
+		}
327
+
328
+		return $markdown;
329
+	}
330
+
331
+
332
+	/**
333
+	 * Convert Image
334
+	 *
335
+	 * Converts <img /> tags to Markdown.
336
+	 *
337
+	 * e.g.	 <img src="/path/img.jpg" alt="alt text" title="Title" />
338
+	 * becomes  ![alt text](/path/img.jpg "Title")
339
+	 *
340
+	 * @param $node
341
+	 * @return string
342
+	 */
343
+	private function convert_image( $node ) {
344
+		$src = $node->getAttribute( 'src' );
345
+		$alt = $node->getAttribute( 'alt' );
346
+		$title = $node->getAttribute( 'title' );
347
+
348
+		if ( $title != '' ) {
349
+			$markdown = '![' . $alt . '](' . $src . ' "' . $title . '")'; // No newlines added. <img> should be in a block-level element.
350
+		} else {
351
+			$markdown = '![' . $alt . '](' . $src . ')';
352
+		}
353
+
354
+		return $markdown;
355
+	}
356
+
357
+
358
+	/**
359
+	 * Convert Anchor
360
+	 *
361
+	 * Converts <a> tags to Markdown.
362
+	 *
363
+	 * e.g.	 <a href="http://modernnerd.net" title="Title">Modern Nerd</a>
364
+	 * becomes  [Modern Nerd](http://modernnerd.net "Title")
365
+	 *
366
+	 * @param $node
367
+	 * @return string
368
+	 */
369
+	private function convert_anchor( $node ) {
370
+		$href = $node->getAttribute( 'href' );
371
+		$title = $node->getAttribute( 'title' );
372
+		$text = $node->nodeValue;
373
+
374
+		if ( $title != '' ) {
375
+			$markdown = '[' . $text . '](' . $href . ' "' . $title . '")';
376
+		} else {
377
+			$markdown = '[' . $text . '](' . $href . ')';
378
+		}
379
+
380
+		// Append a space if the node after this one is also an anchor
381
+		$next_node_name = $this->get_next_node_name( $node );
382
+
383
+		if ( $next_node_name == 'a' ) {
384
+			$markdown = $markdown . ' ';
385
+		}
386
+
387
+		return $markdown;
388
+	}
389
+
390
+
391
+	/**
392
+	 * Convert List
393
+	 *
394
+	 * Converts <ul> and <ol> lists to Markdown.
395
+	 *
396
+	 * @param $node
397
+	 * @return string
398
+	 */
399
+	private function convert_list( $node ) {
400
+		// If parent is an ol, use numbers, otherwise, use dashes
401
+		$list_type = $node->parentNode->nodeName;
402
+		$value = $node->nodeValue;
403
+
404
+		if ( $list_type == 'ul' ) {
405
+			$markdown = '- ' . trim( $value ) . PHP_EOL;
406
+		} else {
407
+			$number = $this->get_position( $node );
408
+			$markdown = $number . '. ' . trim( $value ) . PHP_EOL;
409
+		}
410
+
411
+		return $markdown;
412
+	}
413
+
414
+
415
+	/**
416
+	 * Convert Code
417
+	 *
418
+	 * Convert code tags by indenting blocks of code and wrapping single lines in backticks.
419
+	 *
420
+	 * @param $node
421
+	 * @return string
422
+	 */
423
+	private function convert_code( $node ) {
424
+		// Store the content of the code block in an array, one entry for each line
425
+
426
+		$markdown = '';
427
+
428
+		$code_content = html_entity_decode( $node->C14N() );
429
+		$code_content = str_replace( array( '<code>', '</code>'), '', $code_content );
430
+
431
+		$lines = preg_split( '/\r\n|\r|\n/', $code_content );
432
+		$total = count( $lines );
433
+
434
+		// If there's more than one line of code, prepend each line with four spaces and no backticks.
435
+		if ( $total > 1 ) {
436
+
437
+			// Remove the first and last line if they're empty
438
+			$first_line = trim( $lines[0] );
439
+			$last_line = trim( $lines[$total - 1] );
440
+			$first_line = trim( $first_line, '&#xD;' ); //trim XML style carriage returns too
441
+			$last_line = trim( $last_line, '&#xD;' );
442
+
443
+			if ( empty( $first_line ) ) {
444
+				array_shift( $lines );
445
+			}
446
+
447
+			if ( empty( $last_line ) ) {
448
+				array_pop( $lines );
449
+			}
450
+
451
+			$count = 1;
452
+
453
+			// Add this with the backticks
454
+			$markdown .= '```' . PHP_EOL;
455
+
456
+			foreach ( $lines as $line ) {
457
+				$line = str_replace( '&#xD;', '', $line );
458
+				// Remove the leading tab from the lines (we're using backticks)
459
+				// $markdown .= '	' . $line;
460
+				$markdown .= $line;
461
+				// Add newlines, except final line of the code
462
+				if ( $count != $total ) {
463
+					$markdown .= PHP_EOL;
464
+				}
465
+				$count++;
466
+			}
467
+
468
+			$markdown .= '```' . PHP_EOL;
469
+
470
+		} else { // There's only one line of code. It's a code span, not a block. Just wrap it with backticks.
471
+
472
+			$markdown .= '`' . $lines[0] . '`';
473
+
474
+		}
475
+
476
+		return $markdown;
477
+	}
478
+
479
+
480
+	/**
481
+	 * Convert blockquote
482
+	 *
483
+	 * Prepend blockquotes with > chars.
484
+	 *
485
+	 * @param $node
486
+	 * @return string
487
+	 */
488
+	private function convert_blockquote( $node ) {
489
+		// Contents should have already been converted to Markdown by this point,
490
+		// so we just need to add ">" symbols to each line.
491
+
492
+		$markdown = '';
493
+
494
+		$quote_content = trim( $node->nodeValue );
495
+
496
+		$lines = preg_split( '/\r\n|\r|\n/', $quote_content );
497
+
498
+		$total_lines = count( $lines );
499
+
500
+		foreach ( $lines as $i => $line ) {
501
+			$markdown .= '> ' . $line . PHP_EOL;
502
+			if ( $i + 1 == $total_lines ) {
503
+				$markdown .= PHP_EOL;
504
+
505
+			}
506
+		}
507
+
508
+		return $markdown;
509
+	}
510
+
511
+
512
+	/**
513
+	 * Get Position
514
+	 *
515
+	 * Returns the numbered position of a node inside its parent
516
+	 *
517
+	 * @param $node
518
+	 * @return int The numbered position of the node, starting at 1.
519
+	 */
520
+	private function get_position( $node ) {
521
+		// Get all of the nodes inside the parent
522
+		$list_nodes = $node->parentNode->childNodes;
523
+		$total_nodes = $list_nodes->length;
524
+
525
+		$position = 1;
526
+
527
+		// Loop through all nodes and find the given $node
528
+		for ( $a = 0; $a < $total_nodes; $a++ ) {
529
+			$current_node = $list_nodes->item( $a );
530
+
531
+			if ( $current_node->isSameNode( $node ) ) {
532
+				$position = $a + 1;
533
+			}
534
+		}
535
+
536
+		return $position;
537
+	}
538
+
539
+
540
+	/**
541
+	 * Get Next Node Name
542
+	 *
543
+	 * Return the name of the node immediately after the passed one.
544
+	 *
545
+	 * @param $node
546
+	 * @return string|null The node name (e.g. 'h1') or null.
547
+	 */
548
+	private function get_next_node_name( $node ) {
549
+		$next_node_name = null;
550
+
551
+		$current_position = $this->get_position( $node );
552
+		$next_node = $node->parentNode->childNodes->item( $current_position );
553
+
554
+		if ( $next_node ) {
555
+			$next_node_name = $next_node->nodeName;
556
+		}
557
+
558
+		return $next_node_name;
559
+	}
560
+
561
+
562
+	/**
563
+	 * To String
564
+	 *
565
+	 * Magic method to return Markdown output when HTML_To_Markdown instance is treated as a string.
566
+	 *
567
+	 * @return string
568
+	 */
569
+	public function __toString()
570
+	{
571
+		return $this->output();
572
+	}
573
+
574
+
575
+	/**
576
+	 * Output
577
+	 *
578
+	 * Getter for the converted Markdown contents stored in $this->output
579
+	 *
580
+	 * @return string
581
+	 */
582
+	public function output()
583
+	{
584
+		if ( ! $this->output ) {
585
+			return '';
586
+		} else {
587
+			return $this->output;
588
+		}
589
+	}
590
+}
591
+

+ 167
- 0
export.php View File

@@ -0,0 +1,167 @@
1
+<?php
2
+
3
+require_once(dirname(__FILE__) . '/Idno/start.php');
4
+
5
+include 'HTML-To-Markdown.php';
6
+
7
+function init() {
8
+	$this->garray['data'] = array();
9
+	$this->garray['data']['posts'] = array();
10
+	$this->garray['data']['tags'] = array();
11
+	$this->garray['data']['posts_tags'] = array();
12
+	$this->garray['data']['users'] = array();
13
+}
14
+
15
+function populate_meta() {
16
+	$this->garray['meta'] = array(
17
+		'exported_on' 	=> date( 'r' ),
18
+		'version'		=> '000',
19
+	);
20
+}
21
+
22
+function tags() {
23
+	$all_tags = get_tags();
24
+
25
+	if ( ! empty( $all_tags ) ) {
26
+		foreach ( $all_tags as $tag ) {
27
+			$this->garray['data']['tags'][] = array(
28
+				'id' => intval( $tag->term_id ),
29
+				'name' => $tag->name,
30
+				'slug' => $tag->slug,
31
+				'description' => $tag->description,
32
+			);
33
+		}
34
+	}
35
+
36
+	// cleanup
37
+	unset( $all_tags );
38
+	unset( $tag );
39
+}
40
+
41
+// TODO modifier ça pour Known !
42
+// https://github.com/idno/Known/blob/master/Idno/Common/Entity.php
43
+function posts() {
44
+	
45
+	$posts = Idno\Common\Entity::getFromAll([], [], 99999);
46
+	$slug_number = 0;
47
+	$_post_tags = [];
48
+
49
+	foreach(posts as $post) {
50
+		global $post;
51
+		$posts->the_post();
52
+
53
+		$post->post_markdown = new HTML_To_Markdown( apply_filters( 'the_content', $post->post_content ) );
54
+
55
+		$tags = get_the_tags();
56
+		if ( ! empty( $tags ) ) {
57
+			foreach ( $tags as $tag ) {
58
+				$_post_tags[] = array(
59
+					'tag_id' => intval( $tag->term_id ),
60
+					'post_id' => intval( $post->ID )
61
+				);
62
+			}
63
+		}
64
+
65
+		$s = $this->map_status( $post->post_status );
66
+
67
+		$image_id = get_post_thumbnail_id( $post->ID );
68
+		if ( $image_id !== '' ) {
69
+			$image = wp_get_attachment_image_src( $image_id, 'full' );
70
+		}
71
+
72
+		$this->garray['data']['posts'][] = array(
73
+			//'id'			=> intval( $post->ID ),
74
+			'title'			=> substr( ( empty( $post->title ) ) ? '(no title)' : $post->post_title, 0, 150 ),
75
+			'slug'			=> substr( ( empty( $post->post_name ) ) ? 'temp-slug-' . $slug_number : $post->post_name, 0, 150 ),
76
+			'markdown'		=> $post->post_markdown->output(),
77
+			'html'			=> apply_filters( 'the_content', $post->post_content ),
78
+			'image'			=> ( $image_id ) ? $image[0] : null,
79
+			'featured'		=> 0,
80
+			'page'			=> ( $post->post_type === 'page' ) ? 1 : 0,
81
+			'status'		=> substr( $s, 0, 150 ),
82
+			'language'		=> substr( 'en_US', 0, 6 ),
83
+			'meta_title'	=> null,
84
+			'meta_description'	=> null,
85
+			'author_id'		=> $this->_safe_author_id( $post->post_author ),
86
+			'created_at'	=> $this->_get_json_date( $post->post_date ),
87
+			'created_by'	=> 1,
88
+			'updated_at'	=> $this->_get_json_date( $post->post_modified ),
89
+			'updated_by'	=> 1,
90
+			'published_at'	=> ($s !== 'draft') ? $this->_get_json_date( $post->post_date ) : '',
91
+			'published_by'	=> 1,
92
+		);
93
+
94
+		$slug_number += 1;
95
+	}
96
+
97
+	$this->garray['data']['posts_tags'] = $_post_tags;
98
+
99
+	// cleanup
100
+	unset( $posts_args );
101
+	unset( $posts );
102
+	unset( $slug_number );
103
+	unset( $_post_tags );
104
+	unset( $tags );
105
+	unset( $tag );
106
+	unset( $s );
107
+}
108
+
109
+function populate_data() {
110
+	if ( $this->garray !== null ) {
111
+		return;
112
+	}
113
+
114
+	$this->garray = array();
115
+
116
+	// preps the structure
117
+	init();
118
+
119
+	// attaches metadata
120
+	meta();
121
+
122
+	// attaches tags
123
+	tags();
124
+
125
+	// populates posts
126
+	posts();
127
+}
128
+
129
+/**
130
+ * Sends necessary headers and whatnot to allow to download file
131
+ * @return bin file
132
+ */
133
+public function download_file() {
134
+
135
+	// Ensure the user accessing the function actually has permission to do this
136
+	if ( ! current_user_can('export') ) {
137
+		wp_die( "<p>You are not allowed to do that.</p>", 'Permission error' );
138
+	}
139
+
140
+	$this->populate_data();
141
+
142
+	$upload_dir = wp_upload_dir();
143
+	$filedir = $upload_dir['path'];
144
+	$filename = 'wp2ghost_export_' . time() . '.json';
145
+
146
+	if ( ! is_writable( $filedir ) ) {
147
+		wp_die( "<p>Uploads directory is not writable, can't save the Ghost json file :/</p><p>Generated by the Ghost plugin version {$this->version}.</p>", 'Directory not writable' );
148
+	}
149
+
150
+	$handle = fopen( $filedir . '/' . $filename, 'w' );
151
+	$content = $this->get_json( $this->garray );
152
+	fwrite( $handle, $content );
153
+	fclose( $handle );
154
+
155
+	header( 'Content-Description: File Transfer' );
156
+	header( 'Content-Type: application/octet-stream' );
157
+	header( 'Content-Disposition: attachment; filename='.$filename );
158
+	header( 'Content-Transfer-Encoding: binary' );
159
+	header( 'Expires: 0' );
160
+	header( 'Cache-Control: must-revalidate' );
161
+	header( 'Pragma: public' );
162
+	header( 'Content-Length: ' . filesize( $filedir . '/' . $filename ) );
163
+
164
+	flush();
165
+	readfile( $filedir . '/' . $filename );
166
+	exit;
167
+}

Loading…
Cancel
Save