View source
<?php
class InstapageCmsPluginPageModel {
private static $pageModel = null;
private static $statCacheDuration = 15;
public static function getInstance() {
if (self::$pageModel === null) {
self::$pageModel = new InstapageCmsPluginPageModel();
}
return self::$pageModel;
}
public function update($data) {
$id = isset($data->id) ? $data->id : 0;
$instapageId = isset($data->landingPageId) ? $data->landingPageId : null;
$type = isset($data->type) ? $data->type : false;
$slug = isset($data->slug) ? $data->slug : false;
$enterpriseUrl = InstapageCmsPluginConnector::getHomeURL();
if ($slug) {
$enterpriseUrl .= '/' . $slug;
}
$db = InstapageCmsPluginDBModel::getInstance();
$sql = 'INSERT INTO ' . $db->pagesTable . ' VALUES(%s, %s, %s, %s, NOW(), \'\', NULL, %s) ON DUPLICATE KEY UPDATE instapage_id = %s, slug = %s, type = %s, time = NOW(), stats_cache = \'\', stats_cache_expires = NULL, enterprise_url = %s';
if ($db
->query($sql, $id, $instapageId, $slug, $type, $enterpriseUrl, $instapageId, $slug, $type, $enterpriseUrl)) {
return $id == 0 ? $db
->lastInsertId() : $id;
}
else {
return false;
}
}
public function getAll($fields = array(
'*',
), $conditions = array()) {
$db = InstapageCmsPluginDBModel::getInstance();
$sql = 'SELECT ' . implode(', ', $fields) . ' FROM ' . $db->pagesTable;
if (count($conditions)) {
$sql .= ' WHERE ' . implode(' AND ', $conditions);
}
return $db
->getResults($sql);
}
public function get($id, $fields = array(
'*',
)) {
$db = InstapageCmsPluginDBModel::getInstance();
$sql = 'SELECT ' . implode(', ', $fields) . ' FROM ' . $db->pagesTable . ' WHERE id = \'' . $id . '\'';
return $db
->getRow($sql);
}
public function getBySlug($slug, $fields = array(
'*',
)) {
$db = InstapageCmsPluginDBModel::getInstance();
$sql = 'SELECT ' . implode(', ', $fields) . ' FROM ' . $db->pagesTable . ' WHERE slug = %s AND type=\'page\'';
return $db
->getRow($sql, $slug);
}
public function getByType($type, $slug = '', $fields = array(
'*',
)) {
$db = InstapageCmsPluginDBModel::getInstance();
$sql = 'SELECT ' . implode(', ', $fields) . ' FROM ' . $db->pagesTable . ' WHERE type = %s';
if ($slug) {
$sql = $sql . ' AND slug = %s';
return $db
->getRow($sql, $type, $slug);
}
else {
return $db
->getRow($sql, $type);
}
}
public function getByInstapageId($instapageId, $fields = array(
'*',
)) {
$db = InstapageCmsPluginDBModel::getInstance();
$sql = 'SELECT ' . implode(', ', $fields) . ' FROM ' . $db->pagesTable . ' WHERE instapage_id = ' . $instapageId;
return $db
->getResults($sql);
}
public function getPageStatsCache($ids) {
if (!is_array($ids) || !count($ids)) {
return null;
}
$db = InstapageCmsPluginDBModel::getInstance();
foreach ($ids as &$item) {
$item = intval($item);
}
$idsSet = implode(', ', $ids);
$expireInSeconds = self::$statCacheDuration * 60;
$sql = 'SELECT instapage_id, stats_cache FROM ' . $db->pagesTable . ' WHERE instapage_id IN(' . $idsSet . ') AND stats_cache_expires + ' . $expireInSeconds . ' > ' . time();
$results = $db
->getResults($sql);
$stats = array();
if ($results) {
foreach ($results as &$item) {
$stats[$item->instapage_id] = json_decode($item->stats_cache);
}
return $stats;
}
return array();
}
public function publishPage($data) {
$api = InstapageCmsPluginAPIModel::getInstance();
$subaccount = InstapageCmsPluginSubaccountModel::getInstance();
$url = $data->slug ? InstapageCmsPluginConnector::getHomeURL() . '/' . $data->slug : InstapageCmsPluginConnector::getHomeURL();
$url = InstapageCmsPluginHelper::prepareUrlForUpdate($url);
$tokens = isset($data->apiTokens) ? $data->apiTokens : false;
$success = true;
if (!$tokens) {
$tokens = $subaccount
->getAllTokens();
}
$oldPageId = isset($data->id) ? $data->id : null;
$newInstapageId = isset($data->landingPageId) ? $data->landingPageId : null;
if ($oldPageId) {
$oldPage = $this
->get($oldPageId, array(
'instapage_id',
));
if ($oldPage->instapage_id != $newInstapageId) {
$apiData = array(
'page' => $oldPage->instapage_id,
'url' => '',
'publish' => 0,
);
$headers = array(
'accountkeys' => InstapageCmsPluginHelper::getAuthHeader($tokens),
);
$responseJson = $api
->apiCall('page/edit', $apiData, $headers);
$response = json_decode($responseJson);
if (!InstapageCmsPluginHelper::checkResponse($response, null, false) || !$response->success) {
$success = false;
}
}
}
if ($success) {
$apiData = array(
'page' => $data->landingPageId,
'url' => $url,
'publish' => 1,
);
$headers = array(
'accountkeys' => InstapageCmsPluginHelper::getAuthHeader($tokens),
);
$responseJson = $api
->apiCall('page/edit', $apiData, $headers);
$response = json_decode($responseJson);
}
if (!$success || !InstapageCmsPluginHelper::checkResponse($response, null, false) || !$response->success) {
if (isset($response->message) && $response->message !== '') {
return InstapageCmsPluginHelper::formatJsonMessage(InstapageCmsPluginConnector::lang($response->message), 'ERROR');
}
else {
return InstapageCmsPluginHelper::formatJsonMessage(InstapageCmsPluginConnector::lang('There was an error during page update process.'), 'ERROR');
}
return false;
}
$updatedId = $this
->update($data);
if ($updatedId) {
return json_encode((object) array(
'status' => 'OK',
'message' => InstapageCmsPluginConnector::lang('Page updated successfully.'),
'updatedId' => $updatedId,
));
}
else {
return InstapageCmsPluginHelper::formatJsonMessage(InstapageCmsPluginConnector::lang('There was a database error during page update process.'), 'ERROR');
}
}
public function migrateDeprecatedData($data) {
InstapageCmsPluginHelper::writeDiagnostics($data, 'Migration data');
$raport = array();
if (!is_array($data) || !count($data)) {
return $raport;
}
foreach ($data as $deprecatedPage) {
if ($deprecatedPage->type == 'home') {
$deprecatedPage->slug = '';
}
$landingPagesById = $this
->getByInstapageId($deprecatedPage->landingPageId);
$landingPagesBySlug = null;
$landingPagesByType = null;
if (count($landingPagesById)) {
$newLandingPage = array_pop($landingPagesById);
$raport[] = InstapageCmsPluginConnector::lang('Old version of page (slug: %s, Instapage ID: %s) is present in new database (slug: %s) and won\'t be migrated.', $deprecatedPage->slug, $deprecatedPage->landingPageId, $newLandingPage->slug);
continue;
}
if ($deprecatedPage->slug && $deprecatedPage->type == 'page') {
$landingPagesBySlug = $this
->getBySlug($deprecatedPage->slug);
}
if ($landingPagesBySlug) {
$newLandingPage = $landingPagesBySlug;
$raport[] = InstapageCmsPluginConnector::lang('Slug: %s is already taken in new database. Old page (slug: %s, Instapage ID: %s) won\'t be migrated.', $deprecatedPage->slug, $deprecatedPage->slug, $deprecatedPage->landingPageId);
continue;
}
if ($deprecatedPage->type !== 'page') {
$landingPagesByType = $this
->getByType($deprecatedPage->type);
}
if ($landingPagesByType) {
$newLandingPage = $landingPagesByType;
$raport[] = InstapageCmsPluginConnector::lang('One %s page already exists in new database. Old page (slug: %s, Instapage ID: %s) won\'t be migrated.', $deprecatedPage->type, $deprecatedPage->slug, $deprecatedPage->landingPageId);
continue;
}
if ($this
->update($deprecatedPage)) {
$raport[] = InstapageCmsPluginConnector::lang('Old version of page (slug: %s, Instapage ID: %s) successfully migrated.', $deprecatedPage->slug, $deprecatedPage->landingPageId);
}
else {
$raport[] = InstapageCmsPluginConnector::lang('Old version of page (slug: %s, Instapage ID: %s) cannot be migrated due to database error.', $deprecatedPage->slug, $deprecatedPage->landingPageId);
}
}
InstapageCmsPluginHelper::writeDiagnostics($raport, 'Migration raport');
return $raport;
}
public function savePageStatsCache($data) {
$db = InstapageCmsPluginDBModel::getInstance();
foreach ($data as $key => $item) {
$sql = 'UPDATE ' . $db->pagesTable . ' SET stats_cache = %s, stats_cache_expires = ' . time() . ' WHERE instapage_id = %s';
$db
->query($sql, json_encode($item), $key);
}
}
public function getHomepage($fields = array(
'*',
)) {
$db = InstapageCmsPluginDBModel::getInstance();
$sql = 'SELECT ' . implode(', ', $fields) . ' FROM ' . $db->pagesTable . ' WHERE type=\'home\'';
return $db
->getRow($sql);
}
public function get404($fields = array(
'*',
)) {
$db = InstapageCmsPluginDBModel::getInstance();
$sql = 'SELECT ' . implode(', ', $fields) . ' FROM ' . $db->pagesTable . ' WHERE type=\'404\'';
return $db
->getRow($sql);
}
public function mergeListPagesResults(&$localData, $appData) {
foreach ($localData as &$localItem) {
$instapageId = $localItem->instapage_id;
$appItem = $this
->getPageFromArray($instapageId, $appData);
if (!is_null($appItem)) {
$localItem->screenshot = $appItem->screenshot;
$localItem->title = $appItem->title;
$localItem->subaccount = $appItem->subaccount;
}
}
}
public function check($type, $slug = '') {
if (!InstapageCmsPluginConnector::isHtmlReplaceNecessary()) {
return;
}
$result = $this
->getByType($type, $slug, array(
'instapage_id',
'slug',
'enterprise_url',
));
if (!$result) {
return;
}
$result->slug = $result->slug ? $result->slug : $slug;
$result->enterprise_url = $result->enterprise_url ? $result->enterprise_url : InstapageCmsPluginConnector::getHomeURL() . '/' . $result->slug;
$result->enterprise_url = rtrim($result->enterprise_url, '/');
return $result;
}
public function display($page, $forcedStatus = null) {
require_once __DIR__ . '/../modules/lpAjaxLoader/InstapageCmsPluginLPAjaxLoaderController.php';
$lpAjaxLoaderController = new InstapageCmsPluginLPAjaxLoaderController();
$instapageId = $page->instapage_id;
$slug = $page->slug;
$host = parse_url($page->enterprise_url, PHP_URL_HOST);
InstapageCmsPluginHelper::writeDiagnostics($slug . ' : ' . $instapageId, 'slug : instapage_id');
$api = InstapageCmsPluginAPIModel::getInstance();
$querySufix = '';
$cookies = $_COOKIE;
if (!empty($_GET)) {
if ($lpAjaxLoaderController
->shouldDecodeQuery()) {
$querySufix = '?' . base64_decode($_GET['b64']);
}
else {
$querySufix = '?' . http_build_query($_GET);
}
}
elseif (isset($_SERVER['QUERY_STRING']) && !empty($_SERVER['QUERY_STRING'])) {
$querySufix = '?' . $_SERVER['QUERY_STRING'];
}
if (is_array($cookies) && count($cookies)) {
$cookiesWeNeed = array(
"instapage-variant-{$instapageId}",
);
foreach ($cookies as $key => $value) {
if (!in_array($key, $cookiesWeNeed)) {
unset($cookies[$key]);
}
}
}
$url = preg_replace('/https?:\\/\\/' . $host . '/', INSTAPAGE_ENTERPRISE_ENDPOINT, $page->enterprise_url);
$url .= $querySufix;
$url = InstapageCmsPluginConnector::getURLWithSelectedProtocol($url);
$enterpriseCallResult = $api
->enterpriseCall($url, $host, $cookies);
$html = $this
->getLandingPageHTMLFromTheApp($enterpriseCallResult);
$this
->setVariantCookie($enterpriseCallResult, $instapageId);
if ($lpAjaxLoaderController
->shouldBeUsed($url)) {
$html = $lpAjaxLoaderController
->injectScript($html);
$html = $lpAjaxLoaderController
->addDisplayNoneOnBody($html);
}
if ($forcedStatus) {
$status = $forcedStatus;
}
else {
$status = isset($enterpriseCallResult['code']) ? $enterpriseCallResult['code'] : 200;
}
if ($html) {
ob_start();
InstapageCmsPluginHelper::disableCaching();
InstapageCmsPluginHelper::httpResponseCode($status);
print $html;
ob_end_flush();
die;
}
else {
return false;
}
}
public function getLandingPageHTMLFromTheApp($enterpriseCallResult) {
$html = isset($enterpriseCallResult['body']) ? $enterpriseCallResult['body'] : false;
$html = $this
->disableCloudFlareScriptReplace($html);
$html = $this
->fixHtmlHead($html);
return $html;
}
public function setVariantCookie($enterpriseCallResult, $instapageId) {
$pageserverCookie = isset($enterpriseCallResult['headers']['set-cookie']) ? $enterpriseCallResult['headers']['set-cookie'] : '';
if (is_array($pageserverCookie)) {
$pageserverCookie = array_pop($pageserverCookie);
}
$instapageVariant = InstapageCmsPluginHelper::getVariant((string) $pageserverCookie);
if (!empty($instapageVariant)) {
$variantCookieName = "instapage-variant-{$instapageId}";
$variantCookieOptions = [
'expires' => strtotime('+12 month'),
'path' => '/',
'domain' => '',
];
if (InstapageCmsPluginConnector::isSSL()) {
$variantCookieOptions['samesite'] = 'None';
$variantCookieOptions['secure'] = InstapageCmsPluginConnector::isSSL();
}
if (version_compare(phpversion(), '7.3', '<')) {
if (InstapageCmsPluginConnector::isSSL()) {
setcookie($variantCookieName, $instapageVariant, $variantCookieOptions['expires'], $variantCookieOptions['path'] . '; samesite=' . $variantCookieOptions['samesite'], $variantCookieOptions['domain'], $variantCookieOptions['secure']);
}
else {
setcookie($variantCookieName, $instapageVariant, $variantCookieOptions['expires'], $variantCookieOptions['path'], $variantCookieOptions['domain']);
}
}
else {
setcookie($variantCookieName, $instapageVariant, $variantCookieOptions);
}
}
}
public function delete($id) {
$db = InstapageCmsPluginDBModel::getInstance();
$sql = 'DELETE FROM ' . $db->pagesTable . ' WHERE id = %s';
return $db
->query($sql, $id);
}
private function getPageFromArray($id, $array) {
if (is_array($array)) {
foreach ($array as $item) {
if ($item->id == $id) {
return $item;
}
}
}
return null;
}
public function getRandomSlug($prefix = true) {
$randomPrefix = 'random-url-';
$randomSufixSet = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
$randomSufixLength = 10;
$randomString = '';
for ($i = 0; $i < $randomSufixLength; $i++) {
$randomString .= $randomSufixSet[rand(0, strlen($randomSufixSet) - 1)];
}
return $prefix ? $randomPrefix . $randomString : $randomString;
}
private function disableCloudFlareScriptReplace($html) {
$pattern = '/(<script)(type="text\\/javascript")?(.*?)>/';
return preg_replace($pattern, "\$1\$2 data-cfasync=\"false\" \$3>", $html);
}
public function fixHtmlHead($html) {
$useProxy = InstapageCmsPluginHelper::getOption('crossOrigin', false);
if ($useProxy) {
$html = str_replace('PROXY_SERVICES', str_replace(array(
'http://',
'https://',
), array(
'//',
'//',
), InstapageCmsPluginConnector::getHomeURL()) . "/instapage-proxy-services?url=", $html);
}
$searchArray = array(
'<meta name="iy453p9485yheisruhs5" content="" />',
'<meta name="robots" content="noindex, nofollow" />',
);
if (strpos($html, $searchArray[0]) !== false) {
$html = str_replace($searchArray, '', $html);
}
return $html;
}
}