1<?php
2/**
3 * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
4 * @author     Stephan Dekker <Stephan@SparklingSoftware.com.au>
5 */
6
7require_once(DOKU_PLUGIN.'syntax.php');
8require_once(DOKU_PLUGIN.'git/lib/Git.php');
9
10
11/**
12 * All DokuWiki plugins to extend the parser/rendering mechanism
13 * need to inherit from this class
14 */
15class syntax_plugin_git_localstatus extends DokuWiki_Syntax_Plugin {
16
17    var $helper = null;
18
19    function syntax_plugin_git_localstatus (){
20        $this->helper =& plugin_load('helper', 'git');
21        if(!$this->helper) msg('Loading the git helper in the git_localstatus class failed.', -1);
22    }
23
24    /**
25     * return some info
26     */
27    function getInfo(){
28        return array(
29            'author' => 'Stephan Dekker',
30            'email'  => 'Stephan@SparklingSoftware.com.au',
31            'date'   => @file_get_contents(dirname(__FILE__) . '/VERSION'),
32            'name'   => 'Git Remote Status Plugin',
33            'desc'   => 'xml',
34            'url'    => 'http://dokuwiki.org/plugin:git',
35        );
36    }
37
38    /**
39     * What kind of syntax are we?
40     */
41    function getType(){
42        return 'substition';
43    }
44
45    /**
46     * What about paragraphs?
47     */
48    function getPType(){
49        return 'normal';
50    }
51
52    /**
53     * Where to sort in?
54     */
55    function getSort(){
56        return 990;     //was 990
57    }
58
59
60    /**
61     * Connect pattern to lexer
62     */
63    function connectTo($mode) {
64        $this->Lexer->addSpecialPattern('~~GITLocalStatus~~',$mode,'plugin_git_localstatus');
65    }
66
67    /**
68     * Handle the match
69     */
70    function handle($match, $state, $pos, &$handler){
71        $match_array = array();
72        $match = substr($match,11,-2); //strip ~~REVISIONS: from start and ~~ from end
73        // Wolfgang 2007-08-29 suggests commenting out the next line
74        // $match = strtolower($match);
75        //create array, using ! as separator
76        $match_array = explode("!", $match);
77        // $match_array[0] will be all, or syntax error
78        // this return value appears in render() as the $data param there
79        return $match_array;
80    }
81
82    /**
83     * Create output
84     */
85    function render($format, &$renderer, $data) {
86        global $INFO, $conf;
87
88        if($format == 'xhtml'){
89
90            try
91            {
92                // If not logged in, go bugger off...
93                if (is_array($INFO['userinfo']) === false)
94                {
95                    $renderer->doc .= "<br/><br/>You need to be logged in to view this page. Please login.";
96                    return;
97                }
98
99                // Get GIT commits
100                $this->getConf('');
101                $git_exe_path = $conf['plugin']['git']['git_exe_path'];
102                $datapath = $conf['savedir'];
103                $repo = new GitRepo($datapath);
104                $repo->git_path = $git_exe_path;
105
106                // Is there anything waiting to be commited?
107                $waiting_to_commit = $repo->get_status();
108                if ($waiting_to_commit !== "")
109                {
110                    $renderer->doc .= '<h3>These are the files that have changed:</h3>';
111                    $renderer->doc .= '<p>They have not yet been commited. In order to see all changes to the workspace, commit them and reload this page.</p>';
112
113                    // Add a semaphore commit, telling the rendering engine that this isn't a real commit, rather we want to see the current
114                    $commits = array();
115                    if(!empty($commit)) unset($commit);
116                    $commit['hash'] = 'new';
117                    $commits[] = $commit;
118
119                    // Render page
120                    $this->helper->render_changed_files_table($renderer, $commits, $repo);
121                    $this->helper->renderChangesMade($renderer, $repo, 'Commit local');
122                    $this->renderCommitMessage($renderer, $repo);
123
124                    return;
125                }
126
127                // No local changes to be committed. Are we ready to push up?
128                if ($repo->LocalCommitsExist())
129                {
130                    if($this->helper->haveChangesBeenSubmitted() === true)
131                    {
132                        $renderer->doc .= '<h3>There are commits awaiting to the be pushed to Live!</h3>';
133
134                        $this->helper->resetGitStatusCache('upstream');
135                        $upsptreamUpdatesAvailable = $this->helper->CheckForUpstreamUpdates();
136                        if ($upsptreamUpdatesAvailable)
137                        {
138                            $renderer->doc .= '<p>Other initiatives are approved while this has been waiting for approval. Those changes need to be merged into this workspace before these changes can be approved. Click the link in the banner on top of the screen to open the "Upstream changes" page to merge.<br/>';
139                        }
140                        else
141                        {
142                            $renderer->doc .= '<p>One or more commits have been made to this workspace that are ready to be promoted to Live!<br/>';
143                            $renderer->doc .= 'These can include merges with changes made in other workspaces and approved by the SEPG.</p>';
144                            $this->helper->renderAdminApproval($renderer);
145                        }
146
147                        $renderer->doc .= '<br/><br/><p>To investigate the changes made in this workspace please select a commit in the drop down list to view the changes contained in each.</p>';
148                    }
149                    else
150                    {
151                        $renderer->doc .= '<h3>Commits have been made to this workspace that are ready for submission to the SEPG</h3>';
152                        $renderer->doc .= '<p>TODO: add more information here</p>';
153
154                        $this->renderSubmitMessage($renderer, $repo);
155                    }
156
157                    // Get the list of commits since the last push
158                    $log = $repo->get_log('origin/master..HEAD');
159                    $commits = $repo->get_commits($log);
160
161                    // Add the "Everything" semaphore commit
162                    if(!empty($commit)) unset($commit);
163                    $commit['hash'] = 'all';
164                    $commit['message'] = 'All changes to this workspace';
165                    array_push($commits, $commit);
166
167                    // Render combo-box
168                    $renderer->doc .= '<br/><h3>Commits:</h3>';
169                    $this->helper->render_commit_selector($renderer, $commits, true);
170
171                    $this->helper->render_changed_files_table($renderer, $commits, $repo);
172                    $this->helper->renderChangesMade($renderer, $repo, 'Approve Local');
173
174                    return;
175                }
176
177                // None of the above, so there is nothing to do... bugger...
178                $renderer->doc .= "No changes made in this workspace";
179            }
180            catch(Exception $e)
181            {
182                $renderer->doc .= 'Exception happened:<br/>';
183                $renderer->doc .= $e->getMessage();
184            }
185
186            return true;
187        }
188        return false;
189    }
190
191
192
193    function renderCommitMessage(&$renderer, $repo)
194    {
195        $renderer->doc .= "<h3>Please enter a short summary of these intermediate changes</h3>";
196        $renderer->doc .= '<p>This short message will only be used within this workspace and is only intended to designate interim commits. You will be asked to opportunity to provide a detailed description of all the changes just before submitting this entire workspace= for approval.</p>';
197        $renderer->doc .= '<form method="post">';
198        $renderer->doc .= '  <textarea name="CommitMessage" style="width: 800px; height: 80px;" ></textarea></br>';
199        $renderer->doc .= '  <input type="submit" name="cmd[commit_current]"  value="Commit Current Changes" />';
200        $renderer->doc .= '</form><br/>';
201    }
202
203    function renderSubmitMessage(&$renderer, $repo)
204    {
205        $renderer->doc .= "<h3>Please provide a detailed description of ALL the changes to be submitted.</h3>";
206        $renderer->doc .= '<p>Before submitting, please consider the following: Has the content been reviewed for:';
207        $renderer->doc .= '<ol>';
208        $renderer->doc .= '<li>For the IP: Have all the deliverables been implemented? Please refer to the IP (link on the top of the page) to double check.</li>';
209        $renderer->doc .= '<li>For the IP: Have you planned how the adoption of these changes is ensured? Please refer to Adption plans for more information.</li>';
210        $renderer->doc .= '<li>For each page: Is revision frequency specified?</li>';
211        $renderer->doc .= '<li>For each page: Is SEO metadata specified?</li>';
212        $renderer->doc .= '<li>For each page: Are all images implemented as Imagemaps?</li>';
213        $renderer->doc .= '</ol>';
214
215        $renderer->doc .= '<br/><p>And finally: Please note that submitting the changes for approval will make this workspace read-only. Therefore, only submit fully completed IPs.</p>';
216        $renderer->doc .= '<form method="post">';
217        $renderer->doc .= '  <textarea name="CommitMessage" style="width: 800px; height: 80px;" ></textarea></br>';
218        $renderer->doc .= '  <input type="submit" name="cmd[commit_submit]"  value="Submit for approval" />';
219        $renderer->doc .= '</form><br/>';
220    }
221
222
223
224}
225
226
227//Setup VIM: ex: et ts=4 enc=utf-8 :
228?>
229