Version Description
- Added new gallery backup functionality
- Implemented galleries export mode
- Implemented galleries import mode
Download this release
Release Info
Developer | robosoft |
Plugin | Gallery – Photo Gallery and Images Gallery |
Version | 1.7.0 |
Comparing to | |
See all releases |
Code changes from version 1.6.9 to 1.7.0
- includes/extensions/backup/class_backup.php +1083 -0
- includes/extensions/backup/index.html +0 -0
- includes/rbs_gallery_backup.php +83 -0
- includes/rbs_gallery_config.php +0 -1
- includes/rbs_gallery_init.php +26 -1
- includes/rbs_gallery_list.php +5 -9
- includes/rbs_gallery_menu.php +10 -0
- js/admin/backup.js +46 -0
- languages/rbs_gallery-ru_RU.mo +0 -0
- languages/rbs_gallery-ru_RU.po +56 -14
- readme.txt +9 -1
- robogallery.php +2 -2
includes/extensions/backup/class_backup.php
ADDED
@@ -0,0 +1,1083 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/*
|
3 |
+
* Robo Gallery
|
4 |
+
* Version: 1.6
|
5 |
+
* By Robosoft
|
6 |
+
*
|
7 |
+
* Contact: http://robosoft.co
|
8 |
+
* Created: 2015
|
9 |
+
* Licensed under the GPLv2 license - http://opensource.org/licenses/gpl-2.0.php
|
10 |
+
*
|
11 |
+
* Copyright (c) 2014-2015, Robosoft. All rights reserved.
|
12 |
+
* Available only in http://robosoft.co/
|
13 |
+
*/
|
14 |
+
|
15 |
+
class rbsGalleryExport {
|
16 |
+
const ATTACHMENT_MAX_AMOUNT = 1000;
|
17 |
+
const DUPLICATE_PREFIX = 'copy_';
|
18 |
+
const MODE_EXPORT_XML = 'xml';
|
19 |
+
const MODE_EXPORT_ZIP = 'zip';
|
20 |
+
const MODE_IMPORT_XML = 'xml';
|
21 |
+
const MODE_IMPORT_ZIP = 'zip';
|
22 |
+
const POSTMETA_ATTACHED_FILE = '_wp_attached_file';
|
23 |
+
const POSTMETA_ATTACHMENT_METADATA = '_wp_attachment_metadata';
|
24 |
+
const POSTMETA_IMAGES = 'rsg_galleryImages';
|
25 |
+
const SPACE4 = ' ';
|
26 |
+
const SPACE8 = ' ';
|
27 |
+
const TAG_POST_DATA = 'post_data';
|
28 |
+
const XML_DECLARATION = '<?xml version="1.0" encoding="utf-8" ?>';
|
29 |
+
|
30 |
+
/**
|
31 |
+
* Database connection
|
32 |
+
*
|
33 |
+
* @var wpdb
|
34 |
+
*/
|
35 |
+
protected $wpdb;
|
36 |
+
|
37 |
+
/**
|
38 |
+
* Mode of importing/exporting posts
|
39 |
+
*
|
40 |
+
* @var string
|
41 |
+
*/
|
42 |
+
protected $mode;
|
43 |
+
|
44 |
+
/**
|
45 |
+
* Base url of uploaded files
|
46 |
+
*
|
47 |
+
* @var string
|
48 |
+
*/
|
49 |
+
protected $baseFileUrl;
|
50 |
+
|
51 |
+
/**
|
52 |
+
* Bath path of uploaded files
|
53 |
+
*
|
54 |
+
* @var string
|
55 |
+
*/
|
56 |
+
protected $baseFilePath;
|
57 |
+
|
58 |
+
/**
|
59 |
+
* Base archive directory
|
60 |
+
*
|
61 |
+
* @var string
|
62 |
+
*/
|
63 |
+
protected $archiveDir = ABSPATH;
|
64 |
+
|
65 |
+
/**
|
66 |
+
* Size(bytes) of chunk archive for splitting
|
67 |
+
*
|
68 |
+
* @var int
|
69 |
+
*/
|
70 |
+
protected $archiveChunkSize = 0;
|
71 |
+
|
72 |
+
/**
|
73 |
+
* List files for exporting
|
74 |
+
*
|
75 |
+
* @var array
|
76 |
+
*/
|
77 |
+
protected $exportFiles = [];
|
78 |
+
|
79 |
+
/**
|
80 |
+
* Duplicate mode of importing posts data.
|
81 |
+
*
|
82 |
+
* @var int
|
83 |
+
*/
|
84 |
+
public $duplicate = 0;
|
85 |
+
|
86 |
+
/**
|
87 |
+
* Mapping archives
|
88 |
+
* key: archive key
|
89 |
+
* value: ZipArchive object
|
90 |
+
*
|
91 |
+
* @var ZipArchive[]
|
92 |
+
*/
|
93 |
+
protected $archives = [];
|
94 |
+
|
95 |
+
/**
|
96 |
+
* Mapping archive files
|
97 |
+
* key: file path
|
98 |
+
* value: archive key
|
99 |
+
*
|
100 |
+
* @var array
|
101 |
+
*/
|
102 |
+
protected $archiveFiles = [];
|
103 |
+
|
104 |
+
/**
|
105 |
+
* Mapping post ID
|
106 |
+
* key: old post ID
|
107 |
+
* value: new new ID
|
108 |
+
*
|
109 |
+
* @var array
|
110 |
+
*/
|
111 |
+
protected $mappingPostIds = [];
|
112 |
+
|
113 |
+
/**
|
114 |
+
* Mapping attachment IDs
|
115 |
+
* key: old attachment ID
|
116 |
+
* value: new attachment ID
|
117 |
+
*
|
118 |
+
* @var array
|
119 |
+
*/
|
120 |
+
protected $mappingAttachmentIds = [];
|
121 |
+
|
122 |
+
/**
|
123 |
+
* Shared error
|
124 |
+
*
|
125 |
+
* @var string
|
126 |
+
*/
|
127 |
+
protected $error;
|
128 |
+
|
129 |
+
/**
|
130 |
+
* Import posts response
|
131 |
+
*
|
132 |
+
* @var array
|
133 |
+
*/
|
134 |
+
protected $response;
|
135 |
+
|
136 |
+
/**
|
137 |
+
* @constructor
|
138 |
+
*/
|
139 |
+
public function __construct()
|
140 |
+
{
|
141 |
+
global $wpdb;
|
142 |
+
$uploadDir = wp_upload_dir();
|
143 |
+
|
144 |
+
$this->wpdb = $wpdb;
|
145 |
+
$this->baseFileUrl = $uploadDir['baseurl'];
|
146 |
+
$this->baseFilePath = $uploadDir['basedir'] . DIRECTORY_SEPARATOR;
|
147 |
+
}
|
148 |
+
|
149 |
+
/**
|
150 |
+
* Get error
|
151 |
+
*
|
152 |
+
* @return string
|
153 |
+
*/
|
154 |
+
public function getError()
|
155 |
+
{
|
156 |
+
return $this->error;
|
157 |
+
}
|
158 |
+
|
159 |
+
/**
|
160 |
+
* Set path for archive directory
|
161 |
+
*
|
162 |
+
* @param string $dir
|
163 |
+
* @return void
|
164 |
+
*/
|
165 |
+
public function setArchiveDir($dir)
|
166 |
+
{
|
167 |
+
$this->archiveDir = rtrim($dir, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;
|
168 |
+
}
|
169 |
+
|
170 |
+
/**
|
171 |
+
* Get path for archive directory
|
172 |
+
*
|
173 |
+
* @return string
|
174 |
+
*/
|
175 |
+
public function getArchiveDir()
|
176 |
+
{
|
177 |
+
return $this->archiveDir;
|
178 |
+
}
|
179 |
+
|
180 |
+
/**
|
181 |
+
* Set archive chunk size in byte
|
182 |
+
*
|
183 |
+
* @param int $size
|
184 |
+
* @return void
|
185 |
+
*/
|
186 |
+
public function setArchiveChunkSize($size)
|
187 |
+
{
|
188 |
+
$this->archiveChunkSize = abs((int)$size);
|
189 |
+
}
|
190 |
+
|
191 |
+
/**
|
192 |
+
* Get archive chunk size in byte
|
193 |
+
*
|
194 |
+
* @return int
|
195 |
+
*/
|
196 |
+
public function getArchiveChunkSize()
|
197 |
+
{
|
198 |
+
return $this->archiveChunkSize;
|
199 |
+
}
|
200 |
+
|
201 |
+
|
202 |
+
/**
|
203 |
+
* Get export posts xml data for downloading
|
204 |
+
*
|
205 |
+
* @param array $args
|
206 |
+
* @param string $fileName
|
207 |
+
* @return bool
|
208 |
+
*/
|
209 |
+
public function exportPostsXml(array $args = [], $fileName = 'export.xml')
|
210 |
+
{
|
211 |
+
$this->mode = self::MODE_EXPORT_XML;
|
212 |
+
|
213 |
+
$postsXml = $this->exportPosts($args);
|
214 |
+
if ($this->error) {
|
215 |
+
return false;
|
216 |
+
}
|
217 |
+
|
218 |
+
$this->sendDownloadHeader($fileName);
|
219 |
+
echo $postsXml;
|
220 |
+
return true;
|
221 |
+
}
|
222 |
+
|
223 |
+
/**
|
224 |
+
* Send headers for force file download
|
225 |
+
*
|
226 |
+
* @param string $fileName
|
227 |
+
* @return void
|
228 |
+
*/
|
229 |
+
protected function sendDownloadHeader($fileName)
|
230 |
+
{
|
231 |
+
header('Content-Description: File Transfer');
|
232 |
+
header('Content-type: text/xml; charset=utf-8');
|
233 |
+
header('Content-Disposition: attachment; filename="' . $fileName . '"');
|
234 |
+
header('Content-Transfer-Encoding: binary');
|
235 |
+
header('Expires: 0');
|
236 |
+
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
|
237 |
+
header('Pragma: public');
|
238 |
+
}
|
239 |
+
|
240 |
+
public function exportPostsZip(array $args = [], $fileName = 'export.xml')
|
241 |
+
{
|
242 |
+
$this->mode = self::MODE_EXPORT_ZIP;
|
243 |
+
|
244 |
+
$postsXml = $this->exportPosts($args);
|
245 |
+
if ($this->error) {
|
246 |
+
return false;
|
247 |
+
}
|
248 |
+
|
249 |
+
$archiveRootName = str_replace('.xml' , '', $fileName);
|
250 |
+
$this->clearArchive($archiveRootName);
|
251 |
+
if ($this->error) {
|
252 |
+
return false;
|
253 |
+
}
|
254 |
+
|
255 |
+
$zip = new ZipArchive();
|
256 |
+
if (0 == $this->archiveChunkSize) {
|
257 |
+
$archivePath = "{$this->archiveDir}{$archiveRootName}.zip";
|
258 |
+
$zip->open($archivePath, ZipArchive::CREATE);
|
259 |
+
|
260 |
+
$zip->addFromString($fileName, $postsXml);
|
261 |
+
foreach ($this->exportFiles as $exportFile) {
|
262 |
+
$zip->addFile($this->baseFilePath . $exportFile, $exportFile);
|
263 |
+
}
|
264 |
+
} else {
|
265 |
+
$count = 1;
|
266 |
+
$size = 0;
|
267 |
+
$archivePath = "{$this->archiveDir}{$archiveRootName}.{$count}.zip";
|
268 |
+
$zip->open($archivePath, ZipArchive::CREATE);
|
269 |
+
|
270 |
+
$zip->addFromString($fileName, $postsXml);
|
271 |
+
foreach ($this->exportFiles as $exportFile) {
|
272 |
+
$fileSize = filesize($this->baseFilePath . $exportFile);
|
273 |
+
if ($this->archiveChunkSize < $size + $fileSize) {
|
274 |
+
$zip->close();
|
275 |
+
$this->isCreatedArchive($archivePath);
|
276 |
+
if ($this->error) {
|
277 |
+
break;
|
278 |
+
}
|
279 |
+
|
280 |
+
$count++;
|
281 |
+
$size = 0;
|
282 |
+
$archivePath = "{$this->archiveDir}{$archiveRootName}.{$count}.zip";
|
283 |
+
$zip->open($archivePath, ZipArchive::CREATE);
|
284 |
+
}
|
285 |
+
|
286 |
+
$zip->addFile($this->baseFilePath . $exportFile, $exportFile);
|
287 |
+
$size += strlen(gzcompress(file_get_contents($this->baseFilePath . $exportFile)));
|
288 |
+
}
|
289 |
+
}
|
290 |
+
$zip->close();
|
291 |
+
$this->isCreatedArchive($archivePath);
|
292 |
+
if ($this->error) {
|
293 |
+
return false;
|
294 |
+
}
|
295 |
+
|
296 |
+
return true;
|
297 |
+
}
|
298 |
+
|
299 |
+
/**
|
300 |
+
* Clear archive files by root name
|
301 |
+
*
|
302 |
+
* @param string $archiveRootName
|
303 |
+
* @return bool|string
|
304 |
+
*/
|
305 |
+
protected function clearArchive($archiveRootName)
|
306 |
+
{
|
307 |
+
$patternName = "{$archiveRootName}.*.zip";
|
308 |
+
$chunks = glob($this->archiveDir . $patternName, GLOB_ERR);
|
309 |
+
$chunks[] = $this->archiveDir . $archiveRootName . '.zip';
|
310 |
+
|
311 |
+
foreach ($chunks as $chunk) {
|
312 |
+
if (file_exists($chunk) && !unlink($chunk)) {
|
313 |
+
$this->error = sprintf(__('Can not clear archive\'s file: "%s".'), $chunk);
|
314 |
+
return false;
|
315 |
+
}
|
316 |
+
}
|
317 |
+
return true;
|
318 |
+
}
|
319 |
+
|
320 |
+
/**
|
321 |
+
* Check whether created archive
|
322 |
+
*
|
323 |
+
* @param string $archivePath
|
324 |
+
* @return bool
|
325 |
+
*/
|
326 |
+
protected function isCreatedArchive($archivePath)
|
327 |
+
{
|
328 |
+
if (!file_exists($archivePath)) {
|
329 |
+
$this->error = sprintf(__("Didn't save archive with files \"%s\"."), basename($archivePath));
|
330 |
+
return false;
|
331 |
+
}
|
332 |
+
return true;
|
333 |
+
}
|
334 |
+
|
335 |
+
/**
|
336 |
+
* Get export posts data
|
337 |
+
*
|
338 |
+
* @param array $args
|
339 |
+
* @return string
|
340 |
+
*/
|
341 |
+
protected function exportPosts(array $args)
|
342 |
+
{
|
343 |
+
$args = array_merge(
|
344 |
+
[
|
345 |
+
'posts_per_page' => 200,
|
346 |
+
'offset' => 0,
|
347 |
+
'post_type' => 'post',
|
348 |
+
'post_status' => 'publish',
|
349 |
+
],
|
350 |
+
$args,
|
351 |
+
[
|
352 |
+
'orderby' => 'post_parent ID',
|
353 |
+
'order' => 'ASC'
|
354 |
+
]
|
355 |
+
);
|
356 |
+
$step = 0;
|
357 |
+
$out = '';
|
358 |
+
|
359 |
+
$out .= self::XML_DECLARATION . PHP_EOL;
|
360 |
+
$out .= '<posts>' . PHP_EOL;
|
361 |
+
do {
|
362 |
+
$args['offset'] = $args['posts_per_page'] * $step;
|
363 |
+
$posts = get_posts($args);
|
364 |
+
|
365 |
+
foreach ($posts as $post) {
|
366 |
+
// convert stdClass to array
|
367 |
+
$post = (array)$post;
|
368 |
+
|
369 |
+
$out .= self::SPACE4 . '<' . self::TAG_POST_DATA . ' id="' . $post['ID'] . '">' . PHP_EOL;
|
370 |
+
$out .= $this->getPostData($post, self::SPACE8);
|
371 |
+
$out .= $this->getPostMetaData($post['ID'], self::SPACE8);
|
372 |
+
$out .= $this->getAttachmentsData($post['ID'], self::SPACE8);
|
373 |
+
$out .= self::SPACE4 . '</' . self::TAG_POST_DATA . '>' . PHP_EOL;
|
374 |
+
|
375 |
+
if ($this->error) {
|
376 |
+
break;
|
377 |
+
}
|
378 |
+
}
|
379 |
+
|
380 |
+
$step += 1;
|
381 |
+
} while (count($posts) == $args['posts_per_page']);
|
382 |
+
$out .= '</posts>' . PHP_EOL;
|
383 |
+
|
384 |
+
if ($this->error) {
|
385 |
+
return null;
|
386 |
+
}
|
387 |
+
return $out;
|
388 |
+
}
|
389 |
+
|
390 |
+
/**
|
391 |
+
* Get export post data
|
392 |
+
*
|
393 |
+
* @param array $post
|
394 |
+
* @param string $indent
|
395 |
+
* @return string
|
396 |
+
*/
|
397 |
+
protected function getPostData(array $post, $indent = '')
|
398 |
+
{
|
399 |
+
$post = $this->prepareExportData($post);
|
400 |
+
return $this->getContent($post, 'post', $indent);
|
401 |
+
}
|
402 |
+
|
403 |
+
/**
|
404 |
+
* Get export post meta data
|
405 |
+
*
|
406 |
+
* @param int $postId
|
407 |
+
* @param string $indent
|
408 |
+
* @return string
|
409 |
+
*/
|
410 |
+
protected function getPostMetaData($postId, $indent = '')
|
411 |
+
{
|
412 |
+
$rows = get_post_meta($postId, '', true);
|
413 |
+
$postMeta = [];
|
414 |
+
|
415 |
+
foreach ($rows as $metaKey => $metaValues) {
|
416 |
+
if($metaKey!='rbs_gallery_id') $postMeta[$metaKey] = $metaValues[0];
|
417 |
+
}
|
418 |
+
$postMeta = $this->prepareExportData($postMeta);
|
419 |
+
|
420 |
+
return $this->getContent($postMeta, 'postmeta', $indent);
|
421 |
+
}
|
422 |
+
|
423 |
+
/**
|
424 |
+
* Get export post attachments data
|
425 |
+
*
|
426 |
+
* @param int $postId
|
427 |
+
* @param string $indent
|
428 |
+
* @return string
|
429 |
+
*/
|
430 |
+
protected function getAttachmentsData($postId, $indent = '')
|
431 |
+
{
|
432 |
+
$images = $this->getMetaImages($postId);
|
433 |
+
$attachments = $this->getAttachments($images);
|
434 |
+
|
435 |
+
$out = $indent . '<attachments>' . PHP_EOL;
|
436 |
+
foreach ($attachments as $attachment) {
|
437 |
+
$out .= $indent .self::SPACE4 . '<post_data id="' . $attachment['ID'] . '">' . PHP_EOL;
|
438 |
+
$out .= $this->getPostData($attachment, $indent . self::SPACE8);
|
439 |
+
$out .= $this->getPostMetaData($attachment['ID'], $indent . self::SPACE8);
|
440 |
+
$out .= $indent .self::SPACE4 . '</post_data>' . PHP_EOL;
|
441 |
+
|
442 |
+
if (self::MODE_EXPORT_ZIP == $this->mode) {
|
443 |
+
$this->exportFiles[] = trim(str_replace($this->baseFileUrl, '', $attachment['guid']), '/');
|
444 |
+
}
|
445 |
+
}
|
446 |
+
$out .= self::SPACE8 . '</attachments>' . PHP_EOL;
|
447 |
+
|
448 |
+
return $out;
|
449 |
+
}
|
450 |
+
|
451 |
+
/**
|
452 |
+
* Get export data content
|
453 |
+
*
|
454 |
+
* @param array $fields
|
455 |
+
* @param string $wrapper
|
456 |
+
* @param string $indent
|
457 |
+
* @return string
|
458 |
+
*/
|
459 |
+
protected function getContent(array $fields, $wrapper = '', $indent = '')
|
460 |
+
{
|
461 |
+
$out = '';
|
462 |
+
$innerIndent = '';
|
463 |
+
|
464 |
+
if ($wrapper) {
|
465 |
+
$out = $wrapper ? ($indent . '<' . $wrapper . '>' . PHP_EOL) : '';
|
466 |
+
$innerIndent = self::SPACE4;
|
467 |
+
}
|
468 |
+
foreach ($fields as $name => $value) {
|
469 |
+
$out .= $indent . $innerIndent . '<' . $name . '>' . $value . '</' . $name . '>' . PHP_EOL;
|
470 |
+
}
|
471 |
+
if ($wrapper) {
|
472 |
+
$out .= $indent . '</' . $wrapper . '>' . PHP_EOL;
|
473 |
+
}
|
474 |
+
|
475 |
+
return $out;
|
476 |
+
}
|
477 |
+
|
478 |
+
/**
|
479 |
+
* Get post meta images
|
480 |
+
*
|
481 |
+
* @param int $postId
|
482 |
+
* @return array
|
483 |
+
*/
|
484 |
+
protected function getMetaImages($postId)
|
485 |
+
{
|
486 |
+
$images = get_post_meta($postId, self::POSTMETA_IMAGES, true);
|
487 |
+
return is_array($images) ? $images : [];
|
488 |
+
}
|
489 |
+
|
490 |
+
/**
|
491 |
+
* Get post attachments by ids
|
492 |
+
*
|
493 |
+
* @param array $ids
|
494 |
+
* @return array
|
495 |
+
*/
|
496 |
+
protected function getAttachments(array $ids)
|
497 |
+
{
|
498 |
+
$args =[
|
499 |
+
'post__in' => $ids,
|
500 |
+
'post_type' => 'attachment',
|
501 |
+
'posts_per_page' => self::ATTACHMENT_MAX_AMOUNT
|
502 |
+
];
|
503 |
+
$attachments = [];
|
504 |
+
$result = [];
|
505 |
+
|
506 |
+
// indexing by ID and convert stdClass to array
|
507 |
+
foreach (get_posts($args) as $post) {
|
508 |
+
$attachments[$post->ID] = (array)$post;
|
509 |
+
}
|
510 |
+
// sort to ids order
|
511 |
+
foreach ($ids as $id) {
|
512 |
+
if (!isset($attachments[$id])) {
|
513 |
+
continue;
|
514 |
+
}
|
515 |
+
$result[$id] = $attachments[$id];
|
516 |
+
}
|
517 |
+
|
518 |
+
return $result;
|
519 |
+
}
|
520 |
+
|
521 |
+
/**
|
522 |
+
* Prepare data for exporting:
|
523 |
+
* - replacing html entities corresponding xml format
|
524 |
+
*
|
525 |
+
* @param array $data
|
526 |
+
* @return array
|
527 |
+
*/
|
528 |
+
protected function prepareExportData(array $data)
|
529 |
+
{
|
530 |
+
foreach ($data as $key => $value) {
|
531 |
+
if (is_string($value)) {
|
532 |
+
$data[$key] = htmlentities($value, ENT_XML1);
|
533 |
+
}
|
534 |
+
}
|
535 |
+
return $data;
|
536 |
+
}
|
537 |
+
|
538 |
+
|
539 |
+
/**
|
540 |
+
* Import posts, postmeta, attachments from *.xml file
|
541 |
+
*
|
542 |
+
* @param string $fileXmlPath
|
543 |
+
* @return array
|
544 |
+
*/
|
545 |
+
public function importPostsXml($fileXmlPath)
|
546 |
+
{
|
547 |
+
$this->mode = self::MODE_IMPORT_XML;
|
548 |
+
|
549 |
+
$xml = file_get_contents($fileXmlPath);
|
550 |
+
return $this->importPosts($xml);
|
551 |
+
}
|
552 |
+
|
553 |
+
/**
|
554 |
+
* Import posts, postmeta, attachments from archive
|
555 |
+
*
|
556 |
+
* @param string $archivePath
|
557 |
+
* @return array
|
558 |
+
*/
|
559 |
+
public function importPostsZip($archivePath)
|
560 |
+
{
|
561 |
+
$this->mode = self::MODE_IMPORT_ZIP;
|
562 |
+
|
563 |
+
$this->response = [
|
564 |
+
'import' => [
|
565 |
+
'post' => 0,
|
566 |
+
'element' => 0,
|
567 |
+
'file' => 0,
|
568 |
+
],
|
569 |
+
'duplicate' => [
|
570 |
+
'post' => 0,
|
571 |
+
'element' => 0,
|
572 |
+
'file' => 0,
|
573 |
+
],
|
574 |
+
'skipped' => [
|
575 |
+
'post' => 0,
|
576 |
+
'element' => 0,
|
577 |
+
'file' => 0,
|
578 |
+
],
|
579 |
+
'errors' => []
|
580 |
+
];
|
581 |
+
|
582 |
+
$this->readArchive($archivePath);
|
583 |
+
if ($this->error) {
|
584 |
+
$this->response['errors'][] = $this->error;
|
585 |
+
return $this->response;
|
586 |
+
}
|
587 |
+
|
588 |
+
$archiveRootName = preg_replace('/(\.[0-9]+)?\.zip$/', '', basename($archivePath));
|
589 |
+
$postsXmlFile = "{$archiveRootName}.xml";
|
590 |
+
if (!isset($this->archiveFiles[$postsXmlFile])) {
|
591 |
+
$this->response['errors'][] = __("Can't find import xml file in archive.");
|
592 |
+
}
|
593 |
+
$archiveKey = $this->archiveFiles[$postsXmlFile];
|
594 |
+
$archive = $this->archives[$archiveKey];
|
595 |
+
$postsXml = $archive->getFromName($postsXmlFile);
|
596 |
+
|
597 |
+
return $this->importPosts($postsXml);
|
598 |
+
}
|
599 |
+
|
600 |
+
/**
|
601 |
+
* Import posts, postmeta, attachments from xml
|
602 |
+
*
|
603 |
+
* @param string $xml
|
604 |
+
* @return array
|
605 |
+
*/
|
606 |
+
public function importPosts($xml)
|
607 |
+
{
|
608 |
+
$this->response = [
|
609 |
+
'import' => [
|
610 |
+
'post' => 0,
|
611 |
+
'element' => 0,
|
612 |
+
'file' => 0,
|
613 |
+
],
|
614 |
+
'duplicate' => [
|
615 |
+
'post' => 0,
|
616 |
+
'element' => 0,
|
617 |
+
'file' => 0,
|
618 |
+
],
|
619 |
+
'skipped' => [
|
620 |
+
'post' => 0,
|
621 |
+
'element' => 0,
|
622 |
+
'file' => 0,
|
623 |
+
],
|
624 |
+
'errors' => []
|
625 |
+
];
|
626 |
+
|
627 |
+
if (!$this->validateXml($xml)) {
|
628 |
+
$this->response['errors'][] = $this->error;
|
629 |
+
return $this->response;
|
630 |
+
}
|
631 |
+
|
632 |
+
$xmlReader = new XMLReader();
|
633 |
+
if(false === $xmlReader->xml($xml)) {
|
634 |
+
$this->response['errors'][] = __("Can't set xml content for reading.");
|
635 |
+
return $this->response;
|
636 |
+
}
|
637 |
+
|
638 |
+
while ($xmlReader->read() && self::TAG_POST_DATA != $xmlReader->localName);
|
639 |
+
if (self::TAG_POST_DATA != $xmlReader->localName) {
|
640 |
+
$this->response['errors'][] = __('Invalid document of import');
|
641 |
+
return $this->response;
|
642 |
+
}
|
643 |
+
|
644 |
+
while (self::TAG_POST_DATA == $xmlReader->localName) {
|
645 |
+
$xmlPostData = new SimpleXMLElement($xmlReader->readOuterXML());
|
646 |
+
$postData = $this->convertPostData($xmlPostData);
|
647 |
+
|
648 |
+
// reset shared error
|
649 |
+
$this->error = null;
|
650 |
+
$this->importPostData($postData);
|
651 |
+
|
652 |
+
if ($this->error) {
|
653 |
+
$this->response['errors'][] = $this->error;
|
654 |
+
return $this->response;
|
655 |
+
}
|
656 |
+
|
657 |
+
$xmlReader->next(self::TAG_POST_DATA);
|
658 |
+
}
|
659 |
+
|
660 |
+
return $this->response;
|
661 |
+
}
|
662 |
+
|
663 |
+
/**
|
664 |
+
* Import single post with postmeta, attachments
|
665 |
+
*
|
666 |
+
* @param array $postData
|
667 |
+
* @return void
|
668 |
+
*/
|
669 |
+
protected function importPostData(array $postData)
|
670 |
+
{
|
671 |
+
$post = $postData['post'];
|
672 |
+
$postId = $this->findPost($post);
|
673 |
+
|
674 |
+
if (null === $postId) {
|
675 |
+
$newPostId = $this->insertPostData($postData);
|
676 |
+
$newPostId && ($this->response['import']['post'] += 1);
|
677 |
+
} elseif ($postId && 1 == $this->duplicate) {
|
678 |
+
$newPostId = $this->duplicatePostData($postData);
|
679 |
+
$newPostId && ($this->response['duplicate']['post'] += 1);
|
680 |
+
} else {
|
681 |
+
$this->response['skipped']['post'] += 1;
|
682 |
+
}
|
683 |
+
}
|
684 |
+
|
685 |
+
/**
|
686 |
+
* Insert post with postmeta, attachments
|
687 |
+
*
|
688 |
+
* @param array $postData
|
689 |
+
* @return int|null
|
690 |
+
*/
|
691 |
+
protected function insertPostData(array $postData)
|
692 |
+
{
|
693 |
+
$post = $postData['post'];
|
694 |
+
$postMeta = isset($postData['postmeta']) ? $postData['postmeta'] : [];
|
695 |
+
$attachments = isset($postData['attachments']) ? $postData['attachments'] : [];
|
696 |
+
$attachmentIds = [];
|
697 |
+
|
698 |
+
$postId = $this->insertPost($post);
|
699 |
+
if (null === $postId) {
|
700 |
+
return null;
|
701 |
+
}
|
702 |
+
|
703 |
+
foreach ($attachments as $attachmentData) {
|
704 |
+
$attachmentId = $this->importAttachmentData($attachmentData);
|
705 |
+
if ($attachmentId) {
|
706 |
+
$attachmentIds[] = $attachmentId;
|
707 |
+
}
|
708 |
+
}
|
709 |
+
|
710 |
+
if (!empty($attachmentIds)) {
|
711 |
+
$postMeta[self::POSTMETA_IMAGES] = $attachmentIds;
|
712 |
+
}
|
713 |
+
$this->addPostMeta($postId, $postMeta);
|
714 |
+
|
715 |
+
return $postId;
|
716 |
+
}
|
717 |
+
|
718 |
+
/**
|
719 |
+
* Duplicate post with postmeta, attachments
|
720 |
+
*
|
721 |
+
* @param array $postData
|
722 |
+
* @return int|null
|
723 |
+
*/
|
724 |
+
protected function duplicatePostData(array $postData)
|
725 |
+
{
|
726 |
+
$post = $postData['post'];
|
727 |
+
$postName = $post['post_name'];
|
728 |
+
$postTitle = $post['post_title'];
|
729 |
+
$count = 0;
|
730 |
+
|
731 |
+
$post['post_name'] = self::DUPLICATE_PREFIX . $postName;
|
732 |
+
$post['post_title'] = self::DUPLICATE_PREFIX . $postTitle;
|
733 |
+
while ($postId = $this->findPost($post)) {
|
734 |
+
$count++;
|
735 |
+
$post['post_name'] = self::DUPLICATE_PREFIX . "{$count}_{$postName}";
|
736 |
+
$post['post_title'] = self::DUPLICATE_PREFIX . "{$count}_{$postTitle}";
|
737 |
+
}
|
738 |
+
|
739 |
+
$postData['post'] = $post;
|
740 |
+
return $this->insertPostData($postData);
|
741 |
+
}
|
742 |
+
|
743 |
+
/**
|
744 |
+
* Import attachment post with postmeta
|
745 |
+
*
|
746 |
+
* @param array $attachmentData
|
747 |
+
* @return int|null
|
748 |
+
*/
|
749 |
+
protected function importAttachmentData(array $attachmentData)
|
750 |
+
{
|
751 |
+
$attachment = $attachmentData['post'];
|
752 |
+
|
753 |
+
if (isset($this->mappingAttachmentIds[$attachment['ID']])) {
|
754 |
+
$this->response['skipped']['element'] += 1;
|
755 |
+
return $this->mappingAttachmentIds[$attachment['ID']];
|
756 |
+
}
|
757 |
+
|
758 |
+
$attachmentId = $this->findPost($attachment);
|
759 |
+
if (null === $attachmentId) {
|
760 |
+
$newAttachmentId = $this->insertAttachmentData($attachmentData);
|
761 |
+
$newAttachmentId && ($this->response['import']['element'] += 1);
|
762 |
+
} elseif ($attachmentId && 1 == $this->duplicate) {
|
763 |
+
$newAttachmentId = $this->duplicateAttachmentData($attachmentData);
|
764 |
+
$newAttachmentId && ($this->response['duplicate']['element'] += 1);
|
765 |
+
} else {
|
766 |
+
$this->response['skipped']['element'] += 1;
|
767 |
+
$newAttachmentId = null;
|
768 |
+
}
|
769 |
+
|
770 |
+
return $newAttachmentId;
|
771 |
+
}
|
772 |
+
|
773 |
+
/**
|
774 |
+
* Insert attachment post with postmeta
|
775 |
+
*
|
776 |
+
* @param array $attachmentData
|
777 |
+
* @return int|null
|
778 |
+
*/
|
779 |
+
protected function insertAttachmentData(array $attachmentData)
|
780 |
+
{
|
781 |
+
$post = $attachmentData['post'];
|
782 |
+
$oldPostId = $post['ID'];
|
783 |
+
$postMeta = isset($attachmentData['postmeta']) ? $attachmentData['postmeta'] : [];
|
784 |
+
$oldAttachmentFile = null;
|
785 |
+
$newAttachmentFile = null;
|
786 |
+
|
787 |
+
if (self::MODE_IMPORT_ZIP == $this->mode && isset($postMeta[self::POSTMETA_ATTACHED_FILE])) {
|
788 |
+
$oldAttachmentFile = $postMeta[self::POSTMETA_ATTACHED_FILE];
|
789 |
+
$newAttachmentFile = $this->importFile($oldAttachmentFile);
|
790 |
+
|
791 |
+
if (!$newAttachmentFile) {
|
792 |
+
return null;
|
793 |
+
}
|
794 |
+
}
|
795 |
+
|
796 |
+
unset($post['ID']);
|
797 |
+
$post['guid'] = $newAttachmentFile
|
798 |
+
? str_replace($oldAttachmentFile, $newAttachmentFile, $post['guid'])
|
799 |
+
: $post['guid'];
|
800 |
+
$result = wp_insert_post($post, true);
|
801 |
+
if (is_wp_error($result)) {
|
802 |
+
$this->error = sprintf(
|
803 |
+
__('Error insert post attachment with ID: "%d" and guid: "%s". %s'),
|
804 |
+
$oldPostId,
|
805 |
+
$post['guid'],
|
806 |
+
$result->get_error_message()
|
807 |
+
);
|
808 |
+
return null;
|
809 |
+
}
|
810 |
+
$post['ID'] = $result;
|
811 |
+
$this->mappingAttachmentIds[$oldPostId] = $post['ID'];
|
812 |
+
|
813 |
+
if ($newAttachmentFile) {
|
814 |
+
$postMeta[self::POSTMETA_ATTACHED_FILE] = $newAttachmentFile;
|
815 |
+
$postMeta[self::POSTMETA_ATTACHMENT_METADATA] = serialize(wp_generate_attachment_metadata(
|
816 |
+
$post['ID'],
|
817 |
+
$this->baseFilePath . $newAttachmentFile
|
818 |
+
));
|
819 |
+
}
|
820 |
+
$this->addPostMeta($post['ID'], $postMeta);
|
821 |
+
|
822 |
+
return $post['ID'];
|
823 |
+
}
|
824 |
+
|
825 |
+
/**
|
826 |
+
* Duplicate attachment post with postmeta
|
827 |
+
*
|
828 |
+
* @param array $attachmentData
|
829 |
+
* @return int|null
|
830 |
+
*/
|
831 |
+
protected function duplicateAttachmentData(array $attachmentData)
|
832 |
+
{
|
833 |
+
$post = $attachmentData['post'];
|
834 |
+
$postName = $post['post_name'];
|
835 |
+
$postTitle = $post['post_title'];
|
836 |
+
$count = 0;
|
837 |
+
|
838 |
+
$post['post_name'] = self::DUPLICATE_PREFIX . $postName;
|
839 |
+
$post['post_title'] = self::DUPLICATE_PREFIX . $postTitle;
|
840 |
+
while ($post['ID'] = $this->findPost($post)) {
|
841 |
+
$count++;
|
842 |
+
$post['post_name'] = self::DUPLICATE_PREFIX . "{$count}_{$postName}";
|
843 |
+
$post['post_title'] = self::DUPLICATE_PREFIX . "{$count}_{$postTitle}";
|
844 |
+
}
|
845 |
+
|
846 |
+
$attachmentData['post'] = $post;
|
847 |
+
return $this->insertAttachmentData($attachmentData);
|
848 |
+
}
|
849 |
+
|
850 |
+
/**
|
851 |
+
* Check whether correcting xml
|
852 |
+
*
|
853 |
+
* @param string $xml
|
854 |
+
* @return bool
|
855 |
+
*/
|
856 |
+
protected function validateXml($xml)
|
857 |
+
{
|
858 |
+
if (0 !== strpos($xml, self::XML_DECLARATION)) {
|
859 |
+
$this->error = __('Invalid xml content.');
|
860 |
+
return false;
|
861 |
+
}
|
862 |
+
return true;
|
863 |
+
}
|
864 |
+
|
865 |
+
/**
|
866 |
+
* Convert xml element of post data to array
|
867 |
+
*
|
868 |
+
* @param SimpleXMLElement $postData
|
869 |
+
* @return array
|
870 |
+
*/
|
871 |
+
protected function convertPostData(SimpleXMLElement $postData)
|
872 |
+
{
|
873 |
+
$result = [];
|
874 |
+
|
875 |
+
foreach ($postData->post[0] as $name => $value) {
|
876 |
+
$result['post'][$name] = (string)$value;
|
877 |
+
}
|
878 |
+
|
879 |
+
if (isset($postData->postmeta)) {
|
880 |
+
foreach ($postData->postmeta[0] as $name => $value) {
|
881 |
+
$result['postmeta'][$name] = (string)$value;
|
882 |
+
}
|
883 |
+
}
|
884 |
+
|
885 |
+
if (isset($postData->attachments)) {
|
886 |
+
for ($i = 0, $count = count($postData->attachments->post_data); $i < $count; $i++ ) {
|
887 |
+
$attachment = $postData->attachments->post_data[$i];
|
888 |
+
$attachmentId = (string)$attachment->attributes()['id'];
|
889 |
+
|
890 |
+
$result['attachments'][$attachmentId] = $this->convertPostData($attachment);
|
891 |
+
}
|
892 |
+
}
|
893 |
+
|
894 |
+
return $result;
|
895 |
+
}
|
896 |
+
|
897 |
+
/**
|
898 |
+
* Get post ID by post_name or post_title
|
899 |
+
*
|
900 |
+
* @param array $post
|
901 |
+
* @return int|null
|
902 |
+
*/
|
903 |
+
protected function findPost(array $post)
|
904 |
+
{
|
905 |
+
$query = $this->wpdb->prepare(
|
906 |
+
'select ID from `' . $this->wpdb->prefix . 'posts`
|
907 |
+
where post_type="%s" and post_status="%s" and (post_name="%s" or post_title="%s")',
|
908 |
+
$post['post_type'],
|
909 |
+
$post['post_status'],
|
910 |
+
$post['post_name'],
|
911 |
+
$post['post_title']
|
912 |
+
);
|
913 |
+
return $this->wpdb->get_var($query);
|
914 |
+
}
|
915 |
+
|
916 |
+
/**
|
917 |
+
* Prepare and insert post
|
918 |
+
*
|
919 |
+
* @param array $post
|
920 |
+
* @return int|null
|
921 |
+
*/
|
922 |
+
protected function insertPost(array $post)
|
923 |
+
{
|
924 |
+
$oldPostId = $post['ID'];
|
925 |
+
|
926 |
+
unset($post['ID']);
|
927 |
+
unset($post['guid']);
|
928 |
+
if (isset($this->mappingPostIds[$post['post_parent']])) {
|
929 |
+
$post['post_parent'] = $this->mappingPostIds[$post['post_parent']];
|
930 |
+
}
|
931 |
+
|
932 |
+
$result = wp_insert_post($post, true);
|
933 |
+
if (is_wp_error($result)) {
|
934 |
+
$this->response['errors'][] = sprintf(
|
935 |
+
__('Error insert post with ID: "%d" and title: "%s". %s'),
|
936 |
+
$oldPostId,
|
937 |
+
$post['post_title'],
|
938 |
+
$result->get_error_message()
|
939 |
+
);
|
940 |
+
return null;
|
941 |
+
}
|
942 |
+
|
943 |
+
$this->mappingPostIds[$oldPostId] = $result;
|
944 |
+
return $result;
|
945 |
+
}
|
946 |
+
|
947 |
+
/**
|
948 |
+
* Add post meta values
|
949 |
+
*
|
950 |
+
* @param int $postId
|
951 |
+
* @param array $postMeta
|
952 |
+
* @return void
|
953 |
+
*/
|
954 |
+
protected function addPostMeta($postId, array $postMeta)
|
955 |
+
{
|
956 |
+
foreach ($postMeta as $metaKey => $metaValue) {
|
957 |
+
// check whether meta value is serialized
|
958 |
+
$value = @unserialize($metaValue);
|
959 |
+
if (false !== $value) {
|
960 |
+
$metaValue = $value;
|
961 |
+
}
|
962 |
+
|
963 |
+
$result = add_post_meta($postId, $metaKey, $metaValue);
|
964 |
+
if (false === $result) {
|
965 |
+
$this->response['errors'][] = sprintf(
|
966 |
+
__('Error insert postmeta for post with ID %d. Meta key: "%s", meta value: "%s"'),
|
967 |
+
$postId,
|
968 |
+
$metaKey,
|
969 |
+
$metaValue
|
970 |
+
);
|
971 |
+
continue;
|
972 |
+
}
|
973 |
+
}
|
974 |
+
}
|
975 |
+
|
976 |
+
protected function readArchive($archivePath)
|
977 |
+
{
|
978 |
+
$archiveDir = dirname($archivePath) . DIRECTORY_SEPARATOR;
|
979 |
+
$archiveName = basename($archivePath);
|
980 |
+
$archives = [];
|
981 |
+
|
982 |
+
if (preg_match('/^(.+)\.([0-9]+)\.zip$/', $archiveName, $match)) {
|
983 |
+
$archiveRootName = $match[1];
|
984 |
+
$archiveIndex = $match[2];
|
985 |
+
|
986 |
+
$archiveChunkPath = "{$archiveDir}{$archiveRootName}.{$archiveIndex}.zip";
|
987 |
+
while(file_exists($archiveChunkPath)) {
|
988 |
+
$archives[] = $archiveChunkPath;
|
989 |
+
$archiveIndex++;
|
990 |
+
$archiveChunkPath = "{$archiveDir}{$archiveRootName}.{$archiveIndex}.zip";
|
991 |
+
}
|
992 |
+
} else {
|
993 |
+
$archives[] = $archivePath;
|
994 |
+
}
|
995 |
+
|
996 |
+
foreach ($archives as $index => $archive) {
|
997 |
+
$this->readSingleArchive("archive-{$index}", $archive);
|
998 |
+
if ($this->error) {
|
999 |
+
break;
|
1000 |
+
}
|
1001 |
+
}
|
1002 |
+
|
1003 |
+
return $this->error ? false : true;
|
1004 |
+
}
|
1005 |
+
|
1006 |
+
/**
|
1007 |
+
* Read list files from single archive
|
1008 |
+
*
|
1009 |
+
* @param string $key
|
1010 |
+
* @param string $path
|
1011 |
+
* @return bool
|
1012 |
+
*/
|
1013 |
+
protected function readSingleArchive($key, $path)
|
1014 |
+
{
|
1015 |
+
$zip = new ZipArchive();
|
1016 |
+
|
1017 |
+
if(true !== $zip->open($path)) {
|
1018 |
+
$this->error = sprintf(__("Can't open archive \"%s\"."), basename($path));
|
1019 |
+
return false;
|
1020 |
+
}
|
1021 |
+
$this->archives[$key] = $zip;
|
1022 |
+
|
1023 |
+
for ($i = 0; $i < $zip->numFiles; $i++) {
|
1024 |
+
$stat = $zip->statIndex($i);
|
1025 |
+
$this->archiveFiles[$stat['name']] = $key;
|
1026 |
+
}
|
1027 |
+
|
1028 |
+
return true;
|
1029 |
+
}
|
1030 |
+
|
1031 |
+
/**
|
1032 |
+
* Import single file from archive to upload directory
|
1033 |
+
*
|
1034 |
+
* @param string $file
|
1035 |
+
* @return bool|string
|
1036 |
+
*/
|
1037 |
+
protected function importFile($file)
|
1038 |
+
{
|
1039 |
+
if (!isset($this->archiveFiles[$file])) {
|
1040 |
+
$this->error = sprintf(__("Can't import file \"%s\". File is absent in archive"), $file);
|
1041 |
+
return false;
|
1042 |
+
}
|
1043 |
+
|
1044 |
+
$archiveKey = $this->archiveFiles[$file];
|
1045 |
+
$archive = $this->archives[$archiveKey];
|
1046 |
+
$uploadDir = dirname($file) . DIRECTORY_SEPARATOR;
|
1047 |
+
$fileName = basename($file);
|
1048 |
+
$filePath = $this->baseFilePath . $uploadDir . $fileName;
|
1049 |
+
|
1050 |
+
if (file_exists($filePath) && 0 == $this->duplicate) {
|
1051 |
+
$this->response['skipped']['file'] += 1;
|
1052 |
+
return $file;
|
1053 |
+
}
|
1054 |
+
if (file_exists($filePath) && 1 == $this->duplicate) {
|
1055 |
+
$count = 0;
|
1056 |
+
$duplicateFileName = self::DUPLICATE_PREFIX . $fileName;
|
1057 |
+
$duplicateFilePath = $this->baseFilePath . $uploadDir . $fileName;
|
1058 |
+
while (file_exists($duplicateFilePath)) {
|
1059 |
+
$count++;
|
1060 |
+
$duplicateFileName = self::DUPLICATE_PREFIX . "{$count}_{$fileName}";
|
1061 |
+
$duplicateFilePath = $this->baseFilePath . $uploadDir . $duplicateFileName;
|
1062 |
+
}
|
1063 |
+
|
1064 |
+
$fileName = $duplicateFileName;
|
1065 |
+
$filePath = $duplicateFilePath;
|
1066 |
+
$this->response['duplicate']['file'] += 1;
|
1067 |
+
} else {
|
1068 |
+
$this->response['import']['file'] += 1;
|
1069 |
+
}
|
1070 |
+
|
1071 |
+
if (!file_exists($this->baseFilePath . $uploadDir) && mkdir($this->baseFilePath . $uploadDir, 0777, true)) {
|
1072 |
+
$this->error = sprintf(__("Can't create directory \"%s\" during import file."), $this->baseFilePath . $uploadDir);
|
1073 |
+
return false;
|
1074 |
+
}
|
1075 |
+
if (!touch($filePath) || !chmod($filePath, 0777)) {
|
1076 |
+
$this->error = sprintf(__("Can't create file \"%s\" during import file."), $file);
|
1077 |
+
return false;
|
1078 |
+
}
|
1079 |
+
file_put_contents($filePath, $archive->getFromName($file));
|
1080 |
+
|
1081 |
+
return $uploadDir . $fileName;
|
1082 |
+
}
|
1083 |
+
}
|
includes/extensions/backup/index.html
ADDED
File without changes
|
includes/rbs_gallery_backup.php
ADDED
@@ -0,0 +1,83 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/*
|
3 |
+
* Robo Gallery
|
4 |
+
* Version: 1.2
|
5 |
+
* By Robosoft
|
6 |
+
*
|
7 |
+
* Contact: http://robosoft.co
|
8 |
+
* Created: 2015
|
9 |
+
* Licensed under the GPLv2 license - http://opensource.org/licenses/gpl-2.0.php
|
10 |
+
*
|
11 |
+
* Copyright (c) 2014-2015, Robosoft. All rights reserved.
|
12 |
+
* Available only in http://robosoft.co/
|
13 |
+
*/
|
14 |
+
|
15 |
+
|
16 |
+
|
17 |
+
wp_enqueue_style ( 'toolbox-gallery-about', ROBO_GALLERY_URL.'css/admin/about.css', array( ), ROBO_GALLERY_VERSION );
|
18 |
+
|
19 |
+
|
20 |
+
if(isset($_POST['rbsSubmitBackup'])){
|
21 |
+
if( check_admin_referer( 'rbs-gallery-backup-import' ) ){
|
22 |
+
if ( $_FILES['rbsBackupFile']['error'] == UPLOAD_ERR_OK && is_uploaded_file($_FILES['rbsBackupFile']['tmp_name'])) {
|
23 |
+
$tmp_name = $_FILES['rbsBackupFile']['tmp_name'];
|
24 |
+
rbs_gallery_include('class_backup.php', ROBO_GALLERY_EXTENSIONS_PATH.'/backup/');
|
25 |
+
|
26 |
+
$wordPressExport = new rbsGalleryExport();
|
27 |
+
//$wordPressExport->setArchiveDir(ABSPATH . 'tmp');
|
28 |
+
//$wordPressExport->setArchiveChunkSize(2000000);
|
29 |
+
//$wordPressExport->exportPostsZip(['post_type' => $postType], 'export.xml');
|
30 |
+
//$wordPressExport->duplicate = $duplicate;
|
31 |
+
|
32 |
+
|
33 |
+
|
34 |
+
$export = new rbsGalleryExport('robo_gallery_table');
|
35 |
+
$result = $export->importPostsXml($tmp_name);
|
36 |
+
echo "<h2>".__('Success Import ', 'rbs_gallery')."</h2>";
|
37 |
+
//print_r($result);
|
38 |
+
}
|
39 |
+
} else {
|
40 |
+
echo "check secrete error ";
|
41 |
+
}
|
42 |
+
|
43 |
+
}
|
44 |
+
?>
|
45 |
+
<div class="wrap">
|
46 |
+
<h1 class="rbs-nobackup">
|
47 |
+
<?php _e('Robo Gallery Backup', 'rbs_gallery'); ?>
|
48 |
+
</h1>
|
49 |
+
<table class="form-table">
|
50 |
+
<tbody>
|
51 |
+
<tr>
|
52 |
+
<th scope="row"><label for="blogname"><?php _e('Export Gallery', 'rbs_gallery'); ?></label></th>
|
53 |
+
<td>
|
54 |
+
<form method="post" enctype="multipart/form-data" class="wp-upload-form" action="<?php echo admin_url().'edit.php?post_type=robo_gallery_table&page=robo-gallery-backup'; ?>">
|
55 |
+
<a href="<?php echo admin_url(); ?>edit.php?post_type=robo_gallery_table&page=robo-gallery-backup&rbsGalleryExport=1" class="button button-primary">Download Backup</a>
|
56 |
+
</form></td>
|
57 |
+
</tr>
|
58 |
+
<tr>
|
59 |
+
<th scope="row"><label for="blogname"><?php _e('Import Gallery', 'rbs_gallery'); ?></label></th>
|
60 |
+
<td>
|
61 |
+
<form method="post" enctype="multipart/form-data" class="wp-upload-form" action="<?php echo admin_url().'edit.php?post_type=robo_gallery_table&page=robo-gallery-backup'; ?>">
|
62 |
+
|
63 |
+
<input id="_wpnonce" name="_wpnonce" value="75248da724" type="hidden">
|
64 |
+
<input name="_wp_http_referer" value="/site/w5/wp-admin/plugin-install.php?tab=upload" type="hidden">
|
65 |
+
<?php wp_nonce_field( 'rbs-gallery-backup-import' ); ?>
|
66 |
+
|
67 |
+
<label class="screen-reader-text" for="pluginzip">Import xml file</label>
|
68 |
+
<input type="file" name="rbsBackupFile" id="rbsBackupFile">
|
69 |
+
<input type="submit" class="button button-primary " value="<?php _e('Upload XML'); ?>" name="rbsSubmitBackup">
|
70 |
+
|
71 |
+
|
72 |
+
</form>
|
73 |
+
</td>
|
74 |
+
</tr>
|
75 |
+
<tr>
|
76 |
+
<td colspan="2"><p class="description" id="rbsBackupFile-description"><?php _e('After backup of the galleries settings with EXPORT option, copy images from server folder: {Wordpress folder}/wp-content/uploads to the new location by FTP'); ?></p></td>
|
77 |
+
|
78 |
+
</tr>
|
79 |
+
</tbody>
|
80 |
+
</table>
|
81 |
+
|
82 |
+
</div>
|
83 |
+
<?php
|
includes/rbs_gallery_config.php
CHANGED
@@ -50,7 +50,6 @@ if( !class_exists('RoboGalleryConfig') ){
|
|
50 |
'text'=> 'How to create shortcode?',
|
51 |
'class'=> 'green'
|
52 |
),
|
53 |
-
|
54 |
);
|
55 |
|
56 |
return $guides[ array_rand( $guides ) ];
|
50 |
'text'=> 'How to create shortcode?',
|
51 |
'class'=> 'green'
|
52 |
),
|
|
|
53 |
);
|
54 |
|
55 |
return $guides[ array_rand( $guides ) ];
|
includes/rbs_gallery_init.php
CHANGED
@@ -144,4 +144,29 @@ rbs_gallery_include(array('rbs_gallery_source.php', 'rbs_gallery_helper.php', 'r
|
|
144 |
|
145 |
/* AJAX */
|
146 |
rbs_gallery_include('rbs_gallery_ajax.php', ROBO_GALLERY_INCLUDES_PATH);
|
147 |
-
rbs_gallery_include('rbs_create_post_ajax.php', ROBO_GALLERY_EXTENSIONS_PATH);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
144 |
|
145 |
/* AJAX */
|
146 |
rbs_gallery_include('rbs_gallery_ajax.php', ROBO_GALLERY_INCLUDES_PATH);
|
147 |
+
rbs_gallery_include('rbs_create_post_ajax.php', ROBO_GALLERY_EXTENSIONS_PATH);
|
148 |
+
|
149 |
+
/* Init function */
|
150 |
+
|
151 |
+
/* backup export + */
|
152 |
+
if(!function_exists('rbs_gallery_export')){
|
153 |
+
function rbs_gallery_export(){
|
154 |
+
if(isset($_GET['rbsGalleryExport']) && $_GET['rbsGalleryExport']==1 ){
|
155 |
+
rbs_gallery_include('class_backup.php', ROBO_GALLERY_EXTENSIONS_PATH.'/backup/');
|
156 |
+
$export = new rbsGalleryExport('robo_gallery_table');
|
157 |
+
$export->setArchiveDir(ABSPATH . 'tmp');
|
158 |
+
$export->isExportFiles = true;
|
159 |
+
$isExport = $export->exportPostsXml(['post_type' => ROBO_GALLERY_TYPE_POST] , 'export.xml');
|
160 |
+
if(!$isExport) {
|
161 |
+
// show pretty error
|
162 |
+
var_dump($export->getError());
|
163 |
+
} else {
|
164 |
+
wp_redirect(get_permalink( 'edit.php?post_type=robo_gallery_table&page=robo-gallery-backup' ));
|
165 |
+
}
|
166 |
+
|
167 |
+
die();
|
168 |
+
}
|
169 |
+
}
|
170 |
+
add_action( 'init', 'rbs_gallery_export' );
|
171 |
+
}
|
172 |
+
/* backup export - */
|
includes/rbs_gallery_list.php
CHANGED
@@ -55,19 +55,15 @@ if(!function_exists('add_rbs_table_columns')){
|
|
55 |
add_filter('manage_'.ROBO_GALLERY_TYPE_POST.'_posts_columns' , 'add_rbs_table_columns');
|
56 |
}
|
57 |
|
|
|
58 |
if(!function_exists('rbs_gallery_robogalleryList')){
|
59 |
function rbs_gallery_robogalleryList (){
|
60 |
-
|
61 |
-
<script type="text/javascript">
|
62 |
jQuery(document).ready( function($){
|
63 |
-
|
64 |
-
|
65 |
-
event.preventDefault();
|
66 |
-
alert("'.__('This function is coming soon!').'");
|
67 |
-
})
|
68 |
});
|
69 |
-
</script>
|
70 |
-
';
|
71 |
wp_enqueue_style ('robo-gallery-list', ROBO_GALLERY_URL.'css/admin/list.css', array( ), ROBO_GALLERY_VERSION );
|
72 |
}
|
73 |
add_action( 'in_admin_header', 'rbs_gallery_robogalleryList' );
|
55 |
add_filter('manage_'.ROBO_GALLERY_TYPE_POST.'_posts_columns' , 'add_rbs_table_columns');
|
56 |
}
|
57 |
|
58 |
+
|
59 |
if(!function_exists('rbs_gallery_robogalleryList')){
|
60 |
function rbs_gallery_robogalleryList (){
|
61 |
+
/* echo '<script type="text/javascript">
|
|
|
62 |
jQuery(document).ready( function($){
|
63 |
+
var rbsButtonBackup = jQuery("<a href=\''.admin_url().'edit.php?post_type=robo_gallery_table&page=robo-gallery-backup\' id=\'rbs_backup_button\' class=\'page-title-action\'>'.__('BackUp').'</a>").appendTo(jQuery(".wrap h1")[0]);
|
64 |
+
//rbsButtonBackup.attr("href", "'.admin_url().'edit.php?post_type=robo_gallery_table&rbsGalleryExport=1");
|
|
|
|
|
|
|
65 |
});
|
66 |
+
</script>';*/
|
|
|
67 |
wp_enqueue_style ('robo-gallery-list', ROBO_GALLERY_URL.'css/admin/list.css', array( ), ROBO_GALLERY_VERSION );
|
68 |
}
|
69 |
add_action( 'in_admin_header', 'rbs_gallery_robogalleryList' );
|
includes/rbs_gallery_menu.php
CHANGED
@@ -54,6 +54,16 @@ if(!function_exists('robo_gallery_settings_submenu_page')){
|
|
54 |
|
55 |
}
|
56 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
57 |
if(!function_exists('robo_gallery_about_submenu_page')){
|
58 |
add_action('admin_menu', 'robo_gallery_about_submenu_page');
|
59 |
function robo_gallery_about_submenu_page() {
|
54 |
|
55 |
}
|
56 |
|
57 |
+
if(!function_exists('robo_gallery_backup_submenu_page')){
|
58 |
+
add_action('admin_menu', 'robo_gallery_backup_submenu_page');
|
59 |
+
function robo_gallery_backup_submenu_page() {
|
60 |
+
add_submenu_page( 'edit.php?post_type=robo_gallery_table', 'Backup', 'Backup', 'manage_options', 'robo-gallery-backup', 'robo_gallery_backup_submenu_page_render' );
|
61 |
+
}
|
62 |
+
function robo_gallery_backup_submenu_page_render(){
|
63 |
+
rbs_gallery_include('rbs_gallery_backup.php', ROBO_GALLERY_INCLUDES_PATH);
|
64 |
+
}
|
65 |
+
}
|
66 |
+
|
67 |
if(!function_exists('robo_gallery_about_submenu_page')){
|
68 |
add_action('admin_menu', 'robo_gallery_about_submenu_page');
|
69 |
function robo_gallery_about_submenu_page() {
|
js/admin/backup.js
ADDED
@@ -0,0 +1,46 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/*
|
2 |
+
* Robo Gallery
|
3 |
+
* Version: 1.0
|
4 |
+
* By Robosoft
|
5 |
+
*
|
6 |
+
* Contact: http://robosoft.co
|
7 |
+
* Created: 2015
|
8 |
+
* Licensed under the GPLv2 license - http://opensource.org/licenses/gpl-2.0.php
|
9 |
+
*
|
10 |
+
* Copyright (c) 2014-2015, Robosoft. All rights reserved.
|
11 |
+
* Available only in http://robosoft.co/
|
12 |
+
*/
|
13 |
+
|
14 |
+
jQuery(function(){
|
15 |
+
var roboBackupGalleryDialog = jQuery("#rbsBackUpBlock")/*.appendTo("body")*/;
|
16 |
+
|
17 |
+
var bodyClass = roboBackupGalleryDialog.data("body");
|
18 |
+
if(bodyClass) jQuery("body").addClass(bodyClass);
|
19 |
+
roboBackupGalleryDialog.dialog({
|
20 |
+
'dialogClass' : 'wp-dialog',
|
21 |
+
'title': roboBackupGalleryDialog.data('title'),
|
22 |
+
'modal' : true,
|
23 |
+
'autoOpen' : roboBackupGalleryDialog.data('open'),
|
24 |
+
'width': '450', // overcomes width:'auto' and maxWidth bug
|
25 |
+
'maxWidth': 450,
|
26 |
+
'height': 'auto',
|
27 |
+
'fluid': true,
|
28 |
+
'resizable': false,
|
29 |
+
'responsive': true,
|
30 |
+
'draggable': false,
|
31 |
+
'closeOnEscape' : true,
|
32 |
+
'buttons' : [{
|
33 |
+
'text' : roboBackupGalleryDialog.data('close'),
|
34 |
+
'class' : 'button button-default rbs_dialog_close',
|
35 |
+
'click' : function() { jQuery(this).dialog('close'); }
|
36 |
+
},
|
37 |
+
{
|
38 |
+
'text' : roboBackupGalleryDialog.data('info'),
|
39 |
+
'class' : 'button-primary rbs_getproversion_blank rbs_close_dialog',
|
40 |
+
'click' : function(){}
|
41 |
+
}
|
42 |
+
],
|
43 |
+
open: function( event, ui ) {}
|
44 |
+
});
|
45 |
+
window['roboBackupGalleryDialog'] = roboBackupGalleryDialog;
|
46 |
+
});
|
languages/rbs_gallery-ru_RU.mo
CHANGED
Binary file
|
languages/rbs_gallery-ru_RU.po
CHANGED
@@ -1,15 +1,15 @@
|
|
1 |
msgid ""
|
2 |
msgstr ""
|
3 |
"Project-Id-Version: Robo Gallery v 1.0.0\n"
|
4 |
-
"POT-Creation-Date: 2015-12-
|
5 |
-
"PO-Revision-Date: 2015-12-
|
6 |
"Last-Translator: RoboSoft Team <team@robosoft.co>\n"
|
7 |
"Language-Team: RoboSoft Team <team@robosoft.co>\n"
|
8 |
"Language: ru_RU\n"
|
9 |
"MIME-Version: 1.0\n"
|
10 |
"Content-Type: text/plain; charset=UTF-8\n"
|
11 |
"Content-Transfer-Encoding: 8bit\n"
|
12 |
-
"X-Generator: Poedit 1.8.
|
13 |
"X-Poedit-Basepath: ../includes\n"
|
14 |
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
|
15 |
"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
|
@@ -17,6 +17,41 @@ msgstr ""
|
|
17 |
"X-Poedit-KeywordsList: __;_e\n"
|
18 |
"X-Poedit-SearchPath-0: .\n"
|
19 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
20 |
#: extensions/rbs_create_post.php:10
|
21 |
msgid "Post manager"
|
22 |
msgstr ""
|
@@ -47,7 +82,7 @@ msgid "Empty gallery ID"
|
|
47 |
msgstr "Пустое id галереи "
|
48 |
|
49 |
#: extensions/rbs_create_post_ajax.php:37
|
50 |
-
#: extensions/rbs_create_post_ajax.php:
|
51 |
msgid "Incorrect gallery ID"
|
52 |
msgstr ""
|
53 |
|
@@ -89,14 +124,14 @@ msgid " created"
|
|
89 |
msgstr ""
|
90 |
|
91 |
#: extensions/rbs_create_post_ajax.php:129
|
92 |
-
#: extensions/rbs_create_post_ajax.php:182
|
93 |
#: extensions/rbs_create_post_ajax.php:183
|
|
|
94 |
msgid "Edit"
|
95 |
msgstr ""
|
96 |
|
97 |
#: extensions/rbs_create_post_ajax.php:132
|
98 |
-
#: extensions/rbs_create_post_ajax.php:187
|
99 |
#: extensions/rbs_create_post_ajax.php:188
|
|
|
100 |
msgid "Preview"
|
101 |
msgstr ""
|
102 |
|
@@ -105,7 +140,7 @@ msgid "Error: input value"
|
|
105 |
msgstr "Ошибка: входящее значение"
|
106 |
|
107 |
#: extensions/rbs_create_post_ajax.php:150
|
108 |
-
#: extensions/rbs_create_post_ajax.php:
|
109 |
msgid "Error: "
|
110 |
msgstr "Ошибка:"
|
111 |
|
@@ -113,7 +148,7 @@ msgstr "Ошибка:"
|
|
113 |
msgid "Status"
|
114 |
msgstr ""
|
115 |
|
116 |
-
#: extensions/rbs_create_post_ajax.php:
|
117 |
msgid "publish"
|
118 |
msgstr ""
|
119 |
|
@@ -416,8 +451,7 @@ msgstr ""
|
|
416 |
#: options/rbs_gallery_options_info.php:18
|
417 |
#: options/rbs_gallery_options_info.php:31
|
418 |
#: options/rbs_gallery_options_infowide.php:18 rbs_gallery_about.php:63
|
419 |
-
#: rbs_gallery_about.php:64 rbs_gallery_list.php:29
|
420 |
-
#: rbs_gallery_topblock.php:20
|
421 |
msgid "Get Pro version"
|
422 |
msgstr "Получить PRO версию"
|
423 |
|
@@ -728,6 +762,18 @@ msgstr "Дополнительные настройки описания изо
|
|
728 |
msgid "All Rights Reserved"
|
729 |
msgstr "All Rights Reserved."
|
730 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
731 |
#: rbs_gallery_button.php:22 rbs_gallery_media.php:43
|
732 |
msgid "Robo Gallery"
|
733 |
msgstr "Robo Gallery"
|
@@ -787,10 +833,6 @@ msgstr "Shortcode"
|
|
787 |
msgid "BackUp"
|
788 |
msgstr "Резервная копия "
|
789 |
|
790 |
-
#: rbs_gallery_list.php:66
|
791 |
-
msgid "This function is coming soon!"
|
792 |
-
msgstr ""
|
793 |
-
|
794 |
#: rbs_gallery_media.php:58
|
795 |
msgid "Column"
|
796 |
msgstr "Колонка (и)"
|
1 |
msgid ""
|
2 |
msgstr ""
|
3 |
"Project-Id-Version: Robo Gallery v 1.0.0\n"
|
4 |
+
"POT-Creation-Date: 2015-12-18 12:00+0100\n"
|
5 |
+
"PO-Revision-Date: 2015-12-18 12:00+0100\n"
|
6 |
"Last-Translator: RoboSoft Team <team@robosoft.co>\n"
|
7 |
"Language-Team: RoboSoft Team <team@robosoft.co>\n"
|
8 |
"Language: ru_RU\n"
|
9 |
"MIME-Version: 1.0\n"
|
10 |
"Content-Type: text/plain; charset=UTF-8\n"
|
11 |
"Content-Transfer-Encoding: 8bit\n"
|
12 |
+
"X-Generator: Poedit 1.8.6\n"
|
13 |
"X-Poedit-Basepath: ../includes\n"
|
14 |
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
|
15 |
"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
|
17 |
"X-Poedit-KeywordsList: __;_e\n"
|
18 |
"X-Poedit-SearchPath-0: .\n"
|
19 |
|
20 |
+
#: extensions/backup/class_backup.php:294
|
21 |
+
msgid "Invalid document of import"
|
22 |
+
msgstr ""
|
23 |
+
|
24 |
+
#: extensions/backup/class_backup.php:436
|
25 |
+
#, php-format
|
26 |
+
msgid "Error insert post attachment with ID: \"%d\" and guid: \"%s\". %s"
|
27 |
+
msgstr ""
|
28 |
+
|
29 |
+
#: extensions/backup/class_backup.php:488
|
30 |
+
#, php-format
|
31 |
+
msgid "Wrong post type \"%s\""
|
32 |
+
msgstr ""
|
33 |
+
|
34 |
+
#: extensions/backup/class_backup.php:502
|
35 |
+
#, php-format
|
36 |
+
msgid "File \"%s\" does not exist."
|
37 |
+
msgstr ""
|
38 |
+
|
39 |
+
#: extensions/backup/class_backup.php:511
|
40 |
+
msgid "Wrong type of file. Allowed use only *.xml file type."
|
41 |
+
msgstr ""
|
42 |
+
|
43 |
+
#: extensions/backup/class_backup.php:617
|
44 |
+
#, php-format
|
45 |
+
msgid "Error insert post with ID: \"%d\" and title: \"%s\". %s"
|
46 |
+
msgstr ""
|
47 |
+
|
48 |
+
#: extensions/backup/class_backup.php:648
|
49 |
+
#, php-format
|
50 |
+
msgid ""
|
51 |
+
"Error insert postmeta for post with ID %d. Meta key: \"%s\", meta value: \"%s"
|
52 |
+
"\""
|
53 |
+
msgstr ""
|
54 |
+
|
55 |
#: extensions/rbs_create_post.php:10
|
56 |
msgid "Post manager"
|
57 |
msgstr ""
|
82 |
msgstr "Пустое id галереи "
|
83 |
|
84 |
#: extensions/rbs_create_post_ajax.php:37
|
85 |
+
#: extensions/rbs_create_post_ajax.php:171
|
86 |
msgid "Incorrect gallery ID"
|
87 |
msgstr ""
|
88 |
|
124 |
msgstr ""
|
125 |
|
126 |
#: extensions/rbs_create_post_ajax.php:129
|
|
|
127 |
#: extensions/rbs_create_post_ajax.php:183
|
128 |
+
#: extensions/rbs_create_post_ajax.php:184
|
129 |
msgid "Edit"
|
130 |
msgstr ""
|
131 |
|
132 |
#: extensions/rbs_create_post_ajax.php:132
|
|
|
133 |
#: extensions/rbs_create_post_ajax.php:188
|
134 |
+
#: extensions/rbs_create_post_ajax.php:189
|
135 |
msgid "Preview"
|
136 |
msgstr ""
|
137 |
|
140 |
msgstr "Ошибка: входящее значение"
|
141 |
|
142 |
#: extensions/rbs_create_post_ajax.php:150
|
143 |
+
#: extensions/rbs_create_post_ajax.php:171
|
144 |
msgid "Error: "
|
145 |
msgstr "Ошибка:"
|
146 |
|
148 |
msgid "Status"
|
149 |
msgstr ""
|
150 |
|
151 |
+
#: extensions/rbs_create_post_ajax.php:179
|
152 |
msgid "publish"
|
153 |
msgstr ""
|
154 |
|
451 |
#: options/rbs_gallery_options_info.php:18
|
452 |
#: options/rbs_gallery_options_info.php:31
|
453 |
#: options/rbs_gallery_options_infowide.php:18 rbs_gallery_about.php:63
|
454 |
+
#: rbs_gallery_about.php:64 rbs_gallery_list.php:29 rbs_gallery_topblock.php:20
|
|
|
455 |
msgid "Get Pro version"
|
456 |
msgstr "Получить PRO версию"
|
457 |
|
762 |
msgid "All Rights Reserved"
|
763 |
msgstr "All Rights Reserved."
|
764 |
|
765 |
+
#: rbs_gallery_backup.php:36
|
766 |
+
msgid "Robo Gallery Backup"
|
767 |
+
msgstr ""
|
768 |
+
|
769 |
+
#: rbs_gallery_backup.php:37
|
770 |
+
msgid "Import Gallery"
|
771 |
+
msgstr ""
|
772 |
+
|
773 |
+
#: rbs_gallery_backup.php:55
|
774 |
+
msgid "Export Gallery"
|
775 |
+
msgstr ""
|
776 |
+
|
777 |
#: rbs_gallery_button.php:22 rbs_gallery_media.php:43
|
778 |
msgid "Robo Gallery"
|
779 |
msgstr "Robo Gallery"
|
833 |
msgid "BackUp"
|
834 |
msgstr "Резервная копия "
|
835 |
|
|
|
|
|
|
|
|
|
836 |
#: rbs_gallery_media.php:58
|
837 |
msgid "Column"
|
838 |
msgstr "Колонка (и)"
|
readme.txt
CHANGED
@@ -4,7 +4,7 @@ Donate link: http://www.robosoft.co/robogallery
|
|
4 |
Tags: gallery, add gallery, photo gallery, images gallery, media gallery, responsive gallery, gallery image, gallery lightbox, Polaroid gallery, Gallery Plugin, plugin gallery, video gallery, gallery shortcode, responsive images gallery, website gallery, widget gallery, wordpress gallery, wordpress gallery plugin, wordpress photo gallery plugin, wp gallery, wp gallery plugin, wp gallery plugins, multi categories gallery, add galleries, add picture, add pictures, album, best gallery, best gallery plugin, responsive galleries, mobile gallery, mobile galleries, responsive photo gallery, best portfolio, easy media gallery, filterable gallery, filterable portfolio, foto, fotoalbum, fotogalerie, sortable gallery, sortable galleries, free photo gallery, fullscreen gallery, galary, galeri, galerie, galerij, galery, gallary, Galleria, gallerie, galleries, gallery decription, gallery slider, gelary, gellary, gellery, google, grid gallery, image, image album, image gallery, image gallery plugin, image lightbox, image slider, image slideshow, images, jquery, jquery gallery, links, media, multiple pictures, page, pagination gallery, pagination portfolio, photo, photo album, photo albums, photoalbum, photogallery, photos, photoset, picture, pictures, plugin, plugin for gallery, portfolio, portfolio gallery, portfolio plugin, Post, posts, responsive slideshow, responsive wordpress photo gallery, seo image, slide show, slideshow, thumbnail, upload images, upload photos, batch upload, multiply images upload, view images, view pictures, wordpress portfolio plugin, multi-categories gallery, multi categories galleries, robo gallery
|
5 |
Requires at least: 3.3
|
6 |
Tested up to: 4.4
|
7 |
-
Stable tag: 1.
|
8 |
License: GPLv2 or later
|
9 |
License URI: http://www.gnu.org/licenses/gpl-3.0.html
|
10 |
|
@@ -575,6 +575,11 @@ If any problem occurs, please contact us.
|
|
575 |
|
576 |
== Changelog ==
|
577 |
|
|
|
|
|
|
|
|
|
|
|
578 |
= 1.6.9 =
|
579 |
* Added new content to video guides section
|
580 |
* Added link to gallery shortcode tools video guide
|
@@ -854,6 +859,9 @@ If any problem occurs, please contact us.
|
|
854 |
|
855 |
== Upgrade Notice ==
|
856 |
|
|
|
|
|
|
|
857 |
= 1.6.9 =
|
858 |
Added new content to video guides section, added link to gallery shortcode tools video guide
|
859 |
|
4 |
Tags: gallery, add gallery, photo gallery, images gallery, media gallery, responsive gallery, gallery image, gallery lightbox, Polaroid gallery, Gallery Plugin, plugin gallery, video gallery, gallery shortcode, responsive images gallery, website gallery, widget gallery, wordpress gallery, wordpress gallery plugin, wordpress photo gallery plugin, wp gallery, wp gallery plugin, wp gallery plugins, multi categories gallery, add galleries, add picture, add pictures, album, best gallery, best gallery plugin, responsive galleries, mobile gallery, mobile galleries, responsive photo gallery, best portfolio, easy media gallery, filterable gallery, filterable portfolio, foto, fotoalbum, fotogalerie, sortable gallery, sortable galleries, free photo gallery, fullscreen gallery, galary, galeri, galerie, galerij, galery, gallary, Galleria, gallerie, galleries, gallery decription, gallery slider, gelary, gellary, gellery, google, grid gallery, image, image album, image gallery, image gallery plugin, image lightbox, image slider, image slideshow, images, jquery, jquery gallery, links, media, multiple pictures, page, pagination gallery, pagination portfolio, photo, photo album, photo albums, photoalbum, photogallery, photos, photoset, picture, pictures, plugin, plugin for gallery, portfolio, portfolio gallery, portfolio plugin, Post, posts, responsive slideshow, responsive wordpress photo gallery, seo image, slide show, slideshow, thumbnail, upload images, upload photos, batch upload, multiply images upload, view images, view pictures, wordpress portfolio plugin, multi-categories gallery, multi categories galleries, robo gallery
|
5 |
Requires at least: 3.3
|
6 |
Tested up to: 4.4
|
7 |
+
Stable tag: 1.7.0
|
8 |
License: GPLv2 or later
|
9 |
License URI: http://www.gnu.org/licenses/gpl-3.0.html
|
10 |
|
575 |
|
576 |
== Changelog ==
|
577 |
|
578 |
+
= 1.7.0 =
|
579 |
+
* Added new gallery backup functionality
|
580 |
+
* Implemented galleries export mode
|
581 |
+
* Implemented galleries import mode
|
582 |
+
|
583 |
= 1.6.9 =
|
584 |
* Added new content to video guides section
|
585 |
* Added link to gallery shortcode tools video guide
|
859 |
|
860 |
== Upgrade Notice ==
|
861 |
|
862 |
+
= 1.7.0 =
|
863 |
+
Added new gallery backup functionality, Implemented galleries export/import mode
|
864 |
+
|
865 |
= 1.6.9 =
|
866 |
Added new content to video guides section, added link to gallery shortcode tools video guide
|
867 |
|
robogallery.php
CHANGED
@@ -8,7 +8,7 @@
|
|
8 |
* Plugin Name: Robo Gallery
|
9 |
* Plugin URI: http://robosoft.co/robogallery
|
10 |
* Description: A responsive, easy and elegant way to show gallery.
|
11 |
-
* Version: 1.
|
12 |
* Author: RoboSoft (c)
|
13 |
* Author URI: http://robosoft.co/robogallery
|
14 |
* License: GPL-2.0+
|
@@ -19,7 +19,7 @@
|
|
19 |
|
20 |
if ( ! defined( 'WPINC' ) ) die;
|
21 |
define("ROBO_GALLERY", 1);
|
22 |
-
define("ROBO_GALLERY_VERSION", '1.
|
23 |
define("ROBO_GALLERY_PATH", plugin_dir_path( __FILE__ ));
|
24 |
define("ROBO_GALLERY_SPECIAL", 0);
|
25 |
|
8 |
* Plugin Name: Robo Gallery
|
9 |
* Plugin URI: http://robosoft.co/robogallery
|
10 |
* Description: A responsive, easy and elegant way to show gallery.
|
11 |
+
* Version: 1.7.0
|
12 |
* Author: RoboSoft (c)
|
13 |
* Author URI: http://robosoft.co/robogallery
|
14 |
* License: GPL-2.0+
|
19 |
|
20 |
if ( ! defined( 'WPINC' ) ) die;
|
21 |
define("ROBO_GALLERY", 1);
|
22 |
+
define("ROBO_GALLERY_VERSION", '1.7.0');
|
23 |
define("ROBO_GALLERY_PATH", plugin_dir_path( __FILE__ ));
|
24 |
define("ROBO_GALLERY_SPECIAL", 0);
|
25 |
|