static function add_gitblog_submodule() { # Add gitblog submodule $roundtrip_temp = false; $dotgitmodules = gb::$dir . '/.gitmodules'; $did_have_dotgitmodules = is_file($dotgitmodules); $added = array(); $origin_url = 'git://github.com/rsms/gitblog.git'; # first, find the origin url if any $broken_gitblog_repo = false; if (is_dir(gb::$dir . '/.git')) { try { gb::log('deducing remote.origin.url for existing gitblog'); $s = trim(git::exec('config remote.origin.url', null, gb::$dir . '/.git', gb::$dir)); if ($s) { $origin_url = $s; } } catch (GitError $e) { gb::log(LOG_WARNING, 'failed to read config remote.origin.url: %s', $e->getMessage()); $broken_gitblog_repo = true; } } # if gitblog is not a repo or broken, rename existing and clone a fresh copy from upstream if ($broken_gitblog_repo) { $stash_dir = gb::$dir . '.old'; $i = 1; while (file_exists($stash_dir)) { $stash_dir = gb::$dir . '.old' . $i++; } gb::log('moving broken gitblog %s to %s', gb::$dir, $stash_dir); if (!rename(gb::$dir, $stash_dir)) { # Note: This is tricky. If we get here, it probably means we are unable to # write in dirname(gb::$dir) and gb::$site_dir which we will try to do # further down, where we clone a new copy, which will most likely fail # because we can not create a new directory called "gitblog" due to lack of # priveleges. # # Now, one solution would be to: # # git clone origin /tmp/xy # mkdir ./gitblog/old # mv ./gitblog/(?!old)+ ./gitblog/old/ # mv /tmp/xy/* ./gitblog/ # rm -rf ./gitblog/old # # But as this is a very thin use case, almost vanishingly small since # the gitblog itself can not function w/o write rights, we die hard: gb::log(LOG_CRIT, 'unable to replace gitblog with gitblog submodule (mv %s %s) -- directory not writable? Aborting.', gb::$dir, $stash_dir); exit; } } try { # remove "/gitblog" ignore from .gitignore if (self::gitignore_sub('/(?:\\r?\\n)\\/gitblog([\\t\\s \\r\\n]+|^)/m', '$1')) { $added[] = git::add('.gitignore'); } # register (and clone if needed) the gitblog submodule. This might take some time. try { git::exec('submodule --quiet add -b ' . escapeshellarg(self::$branch) . ' -- ' . escapeshellarg($origin_url) . ' gitblog'); # add gitblog $added[] = git::add('gitblog'); } catch (GitError $e) { if (strpos($e->getMessage(), 'already exists in the index') === false) { throw $e; } } # move back old shallow gitblog dir if ($roundtrip_temp) { $old_dst = gb::$dir . '/gitblog.old'; gb::log('moving %s to %s', $roundtrip_temp, $old_dst); if (!@rename($roundtrip_temp, $old_dst)) { gb::log(LOG_ERR, 'failed to move back %s to %s', $roundtrip_temp, $old_dst); } # we want to explicitly checkout the branch we requested git::exec('checkout ' . escapeshellarg(self::$branch), null, gb::$dir . '/.git', gb::$dir); } } catch (Exception $e) { # move back gitblog dir if ($roundtrip_temp) { gb::log('moving %s to %s', $roundtrip_temp, gb::$dir); if (!@rename($roundtrip_temp, gb::$dir)) { gb::log(LOG_ERR, 'failed to move back %s to %s', $roundtrip_temp, gb::$dir); } } # forward exception throw $e; } # if .submodules did not exist when we started, track it if (!$did_have_dotgitmodules && is_file(gb::$site_dir . '/.gitmodules')) { $added[] = git::add('.gitmodules'); } # commit any modifications if ($added) { try { git::commit('added ' . implode(', ', $added), GBUser::findAdmin()->gitAuthor(), $added); } catch (GitError $e) { if (strpos($e->getMessage(), 'no changes added to commit') === false) { throw $e; } } } }
$modified_state = array(); foreach ($state_fields as $k => $discard) { if ($k === 'body') { $modified_state[$k] = $post->rawBody(); } else { $v = $post->{$k}; if ($v instanceof GBDateTime) { $v = strval($v); } $modified_state[$k] = $v; } } } # commit? if ($input['commit']) { git::add($post->name); git::commit(($created ? 'Created' : 'Updated') . ' post ' . r($post->title), gb::$authorized, $post->name); } # build response entity $rsp = array('name' => $post->name, 'version' => $post->id, 'exists' => $post->exists(), 'isTracked' => $post->isTracked(), 'isDirty' => $post->isDirty(), 'state' => $modified_state); # status $status = '200 OK'; if ($created) { $status = '201 Created'; } # send JSON response gb_admin::json_rsp($rsp, $status); gb::log('saved post %s', $post->name); } catch (Exception $e) { gb::log('failed to save post: %s', GBException::format($e, true, false, null, 0)); gb_admin::json_rsp($e->getMessage(), '400 Bad Request');
function writeComments(GBExposedContent $obj) { if (!$obj->comments) { return; } # sort ksort($obj->comments); # init comments db $cdb = $obj->getCommentsDB(); $cdb->autocommitToRepo = false; $cdb->begin(true); try { foreach ($obj->comments as $comment) { $cdb->append($comment); } } catch (Exception $e) { $cdb->rollback(); throw $e; } $cdb->commit(); git::add($cdb->file); }
static function init($add_sample_content = true, $shared = 'true', $theme = 'default', $mkdirmode = 0775) { # sanity check $themedir = gb::$dir . '/themes/' . $theme; if (!is_dir($themedir)) { throw new InvalidArgumentException('no theme named ' . $theme . ' (' . $themedir . 'not found or not a directory)'); } # git init git::init(null, null, $shared); # Create empty standard directories mkdir(gb::$site_dir . '/content/posts', $mkdirmode, true); chmod(gb::$site_dir . '/content', $mkdirmode); chmod(gb::$site_dir . '/content/posts', $mkdirmode); mkdir(gb::$site_dir . '/content/pages', $mkdirmode); chmod(gb::$site_dir . '/content/pages', $mkdirmode); mkdir(gb::$site_dir . '/data', $mkdirmode); chmod(gb::$site_dir . '/data', $mkdirmode); # Create hooks and set basic config gb_maint::repair_repo_setup(); # Copy default data sets $data_skeleton_dir = gb::$dir . '/skeleton/data'; foreach (scandir($data_skeleton_dir) as $name) { if ($name[0] !== '.') { $path = $data_skeleton_dir . '/' . $name; if (is_file($path)) { copy($path, gb::$site_dir . '/data/' . $name); chmod(gb::$site_dir . '/data/' . $name, 0664); } } } # Copy .gitignore copy(gb::$dir . '/skeleton/gitignore', gb::$site_dir . '/.gitignore'); chmod(gb::$site_dir . '/.gitignore', 0664); git::add('.gitignore'); # Copy theme $lnname = gb::$site_dir . '/index.php'; $lntarget = gb_relpath($lnname, $themedir . '/index.php'); symlink($lntarget, $lnname) or exit($lntarget); git::add('index.php'); # Add gb-config.php (might been added already, might be missing and/or # might be ignored by custom .gitignore -- doesn't really matter) git::add('gb-config.php', false); # Add sample content if ($add_sample_content) { # Copy example "about" page copy(gb::$dir . '/skeleton/content/pages/about.html', gb::$site_dir . '/content/pages/about.html'); chmod(gb::$site_dir . '/content/pages/about.html', 0664); git::add('content/pages/about.html'); # Copy example "about/intro" snippet mkdir(gb::$site_dir . '/content/pages/about', $mkdirmode); chmod(gb::$site_dir . '/content/pages/about', $mkdirmode); copy(gb::$dir . '/skeleton/content/pages/about/intro.html', gb::$site_dir . '/content/pages/about/intro.html'); chmod(gb::$site_dir . '/content/pages/about/intro.html', 0664); git::add('content/pages/about/intro.html'); # Copy example "hello world" post $s = file_get_contents(gb::$dir . '/skeleton/content/posts/0000-00-00-hello-world.html'); $s = preg_replace('/published:.+/', 'published: ' . date('H:i:s O'), $s); $name = 'content/posts/' . gmdate('Y/m-d') . '-hello-world.html'; $path = gb::$site_dir . '/' . $name; @mkdir(dirname($path), 0775, true); chmod(dirname($path), 0775); $s = str_replace('0000/00-00-hello-world.html', basename(dirname($name)) . '/' . basename($name), $s); file_put_contents($path, $s); chmod($path, 0664); git::add($name); } return true; }
function commit() { if ($this->txFp === false) { throw new LogicException('transaction is not active'); } $ex = null; try { $did_write = $this->txWriteData(); } catch (Exception $e) { $ex = $e; } $this->txEnd($ex); if ($ex) { throw $ex; } # commit to repo if ($did_write && $this->autocommitToRepo) { gb::log('committing changes to ' . $this->file); if (!($author = $this->autocommitToRepoAuthor)) { $author = GBUser::findAdmin()->gitAuthor(); } $m = $this->autocommitToRepoMessage ? $this->autocommitToRepoMessage : 'autocommit:' . $this->file; git::add($this->file); git::commit($m, $author); # rollback() will handle gb::reset if needed } return $did_write; }
static function _000104($from, $to) { $datadir = gb::$site_dir . '/data/'; $added = array(); # create data/ if (!file_exists($datadir)) { gb::log('creating directory %s', $datadir); mkdir($datadir, 0775); chmod($datadir, 0775); } # load old site.json gb::log('loading %s', gb::$site_dir . '/site.json'); gb::$site_state = is_readable(gb::$site_dir . '/site.json') ? json_decode(file_get_contents(gb::$site_dir . '/site.json'), true) : array(); # move site.json:plugins to data/plugins.json $plugins = isset(gb::$site_state['plugins']) ? gb::$site_state['plugins'] : array(); gb::log('creating data:plugins'); gb::data('plugins')->storage()->set($plugins); unset(gb::$site_state['plugins']); # write data/site.json gb::log('moving %s -> data:site', gb::$site_dir . '/site.json'); # gb_maint::sync_site_state() will be called after this method returns @unlink(gb::$site_dir . '/site.json'); # remove /site.json from .gitignore if (gb_maint::gitignore_sub('/(?:\\r?\\n)\\/site\\.json([\\t\\s \\r\\n]+|^)/m', '$1')) { gb::log('removed "/site.json" from .gitignore'); $added[] = git::add('.gitignore'); } # load settings.json gb::log('loading %s', gb::$site_dir . '/settings.json'); $settings = is_readable(gb::$site_dir . '/settings.json') ? json_decode(file_get_contents(gb::$site_dir . '/settings.json'), true) : array(); # move settings.json:* to data/plugins/* foreach ($settings as $pluginn => $d) { if (!is_array($d)) { $d = $d !== null ? array($d) : array(); } if ($d) { gb::log('copying %s:%s -> data:plugins/%s', gb::$site_dir . '/settings.json', $pluginn, $pluginn); gb::data('plugins/' . $pluginn)->storage()->set($d); } } gb::log('removing old %s', gb::$site_dir . '/settings.json'); @unlink(gb::$site_dir . '/settings.json'); # load gb-users.php $users = array(); if (is_readable(gb::$site_dir . '/gb-users.php')) { gb::log('loading %s', gb::$site_dir . '/gb-users.php'); eval('class GBUserAccount { static function __set_state($state) { return GBUser::__set_state($state); } }'); require gb::$site_dir . '/gb-users.php'; if (isset($db)) { $admin = isset($db['_admin']) ? $db['_admin'] : ''; foreach ($db as $email => $user) { if (is_object($user)) { $user->admin = $email === $admin; $users[$email] = $user; gb::log('transponded user %s', $email); } } } } # move gb-users.php to data/users.json gb::log('moving %s -> data:users', gb::$site_dir . '/gb-users.php'); GBUser::storage()->set($users); @unlink(gb::$site_dir . '/gb-users.php'); # commit any modifications if ($added) { try { git::commit('upgrade 0.1.4 modified ' . implode(', ', $added), GBUser::findAdmin()->gitAuthor(), $added); } catch (GitError $e) { if (strpos($e->getMessage(), 'no changes added to commit') === false) { throw $e; } } } }