svn: /pear2/BugManager/trunk/ src/BugManager/Attachment.php src/BugManager/Issue.php src/BugManager/IssueManager/Mysql.php src/BugManager/Site/PEAR/ActorManager.php www/pearworm/source/class/pearworm/view/IssueEdit.js www/pearworm/source/uploadattachment.php

[email protected] (Greg Beaver) Mon, 27 Sep 2010 03:18:41 +0000
Newsgroups php.pear.cvs,php.pear.core
Message-ID <[email protected]>
cellog                                   Mon, 27 Sep 2010 03:18:41 +0000

Revision: http://svn.php.net/viewvc?view=revision&revision=303777

Log:
attachment upload: working.  Only major thing to implement: milestones.  tracker is nearly ready for use for pear.php.net in alpha stage, need to implement pear2.php.net on the backend, frontend is good to go for both

Changed paths:
    U   pear2/BugManager/trunk/src/BugManager/Attachment.php
    U   pear2/BugManager/trunk/src/BugManager/Issue.php
    U   pear2/BugManager/trunk/src/BugManager/IssueManager/Mysql.php
    U   pear2/BugManager/trunk/src/BugManager/Site/PEAR/ActorManager.php
    U   pear2/BugManager/trunk/www/pearworm/source/class/pearworm/view/IssueEdit.js
    U   pear2/BugManager/trunk/www/pearworm/source/uploadattachment.php
svn-diffs-303777.txt (text/x-diff, 19.3 KB)
Modified: pear2/BugManager/trunk/src/BugManager/Attachment.php
===================================================================
--- pear2/BugManager/trunk/src/BugManager/Attachment.php	2010-09-27 03:03:21 UTC (rev 303776)
+++ pear2/BugManager/trunk/src/BugManager/Attachment.php	2010-09-27 03:18:41 UTC (rev 303777)
@@ -133,6 +133,12 @@
         if (null == $this->info['name']) {
             throw new BadMethodCallException('Cannot attach, set name first');
         }
+        if (null == $this->bug) {
+            throw new BadMethodCallException('Cannot attach, set bug first');
+        }
+        if (!$this->bug->id) {
+            throw new BadMethodCallException('Cannot attach, bug must exist');
+        }
         $newobsoletes = array();
         foreach ($this->newObsoletes as $who) {
             if (file_exists($this->getPatchFullpath($who['name'], $who['revision']))) {
@@ -304,6 +310,16 @@

     function __set($var, $value)
     {
+        if ($var === 'bug') {
+            if ($value instanceof Issue) {
+                $this->bug = $value;
+            } else {
+                throw new ValidationException('Bug must be an PEAR2\BugManager\Issue object');
+            }
+        }
+        if ($var == 'commentid') {
+            $this->commentId = $value;
+        }
         if (array_key_exists($var, $this->info)) {
             $this->info[$var] = Issue::filter('attachment->' . $var, $value, $this->bug);
         }

Modified: pear2/BugManager/trunk/src/BugManager/Issue.php
===================================================================
--- pear2/BugManager/trunk/src/BugManager/Issue.php	2010-09-27 03:03:21 UTC (rev 303776)
+++ pear2/BugManager/trunk/src/BugManager/Issue.php	2010-09-27 03:18:41 UTC (rev 303777)
@@ -715,7 +715,11 @@
     function retrieve()
     {
         $this->issuemanager->retrieve($this->id, $this);
-        $this->oldvalues = $this->newvalues;
+        foreach ($this->newvalues as $key => $value) {
+            if ($value !== null) {
+                $this->oldvalues[$key] = $value;
+            }
+        }
         if (null === $this->oldvalues['assigned']) {
             $this->oldvalues['assigned'] = array();
         }
@@ -975,7 +979,9 @@
         $comment->comment = $text;
         $comment->commenter = $who;
         $comment->timestamp = $timestamp;
-        $this->comments[] = $comment;
+        $comments = $this->comments;
+        $comments[] = $comment;
+        $this->comments = $comments;
         return $comment;
     }


Modified: pear2/BugManager/trunk/src/BugManager/IssueManager/Mysql.php
===================================================================
--- pear2/BugManager/trunk/src/BugManager/IssueManager/Mysql.php	2010-09-27 03:03:21 UTC (rev 303776)
+++ pear2/BugManager/trunk/src/BugManager/IssueManager/Mysql.php	2010-09-27 03:18:41 UTC (rev 303777)
@@ -58,8 +58,14 @@
         } else {
             $this->actorManager = BugManager\Main::site()->defaultActorManager();
         }
+    }
+
+    function getEscaper()
+    {
+        if ($this->escaper) {
+            return $this->escaper;
+        }
         $this->escaper = new BugManager\IssueEscapeDecorator\Mysql($this->mysqli);
-
     }

     /**
@@ -78,7 +84,7 @@

     protected function getInsertSql($bug)
     {
-        $bug->addEscaper($this->escaper);
+        $bug->addEscaper($this->getEscaper());
         $vals = array(
             'assign'          => isset($bug->assigned[0]) ? $bug->assigned[0]->handle : 'NULL',
             'assign2'         => isset($bug->assigned[1]) ? $bug->assigned[1]->handle : 'NULL',
@@ -113,7 +119,7 @@

     function getCommentInsertSql($bug)
     {
-        $bug->addEscaper($this->escaper);
+        $bug->addEscaper($this->getEscaper());
         $ret = array();
         foreach ($bug->comments as $i => $comment) {
             $ret["\nINSERT INTO bugmanager_comments
@@ -133,7 +139,7 @@
     function getAttachmentInsertSql($bug)
     {
         $ret = '';
-        $bug->addEscaper($this->escaper);
+        $bug->addEscaper($this->getEscaper());
         foreach ($bug->attachments as $i => $attachment) {
             $ret .= "\nINSERT INTO bugmanager_patchtracker
                 (bug_id, name, revision, handle, recordversion)
@@ -393,7 +399,9 @@
      */
     function add(Issue $bug)
     {
-        if (null === $this->actorManager->loggedinUser()) {
+        try {
+            \PEAR2\BugManager\Main::site()->defaultActorManager()->loggedinUser(true);
+        } catch (\Exception $e) {
             throw new BugManager\BadMethodCallException('Cannot add an issue, log in first');
         }
         $sql = $this->getInsertSql($bug);
@@ -436,7 +444,7 @@
             'createtimestamp' => 'ts1',
             'modifiedtimestamp' => 'ts2',
         );
-        $bug->addEscaper($this->escaper);
+        $bug->addEscaper($this->getEscaper());
         if (isset($basicdiff['reporter'])) {
             $updatearr[] = 'handle=' . $bug->reporter->handle;
             $updatearr[] = 'email=' . $bug->reporter->email;
@@ -558,10 +566,21 @@
      */
     function update(Issue $bug)
     {
-        if (null === $this->actorManager->loggedinUser()) {
-            throw new BugManager\BadMethodCallException('Cannot update an issue, log in first');
+        $safe = true;
+        try {
+            $user = \PEAR2\BugManager\Main::site()->defaultActorManager()->loggedinUser(true);
+            if ($user->karma < \PEAR2\BugManager\Actor::DEV) {
+                if ($bug->reporter->uniqueId() != $user->uniqueId()) {
+                    $safe = false;
+                }
+            }
+        } catch (\Exception $e) {
+            throw new BugManager\BadMethodCallException('Cannot update an issue, log in first ' . $e->getMessage());
         }
         list($sql, $addsql) = $this->getUpdateSQL($bug);
+        if (!$safe) {
+            $sql = ''; // no updating allowed, only new comments allowed
+        }
         $this->mysqli->multi_query($sql);
         foreach ($addsql as $query => $comment) {
             $this->mysqli->query($query);
@@ -577,7 +596,12 @@
         if (!$bug->id) {
             throw new Exception('Cannot delete an issue that is not yet added');
         }
-        if (null === $this->actorManager->loggedinUser()) {
+        try {
+            $user = \PEAR2\BugManager\Main::site()->defaultActorManager()->loggedinUser(true);
+            if ($user->karma < \PEAR2\BugManager\Actor::ADMIN) {
+                throw new BugManager\BadMethodCallException('Cannot delete an issue, not an admin');
+            }
+        } catch (\Exception $e) {
             throw new BugManager\BadMethodCallException('Cannot delete an issue, log in first');
         }
         $this->mysqli->multi_query('DELETE FROM bugmanager_issues WHERE id=?;
@@ -605,13 +629,13 @@
                 return true;
             }
         }
-        Issue::addEscaper($this->escaper);
         if ($contextname != 'milestones') {
             return false;
         }
         if (!($value instanceof BugManager\Milestone)) {
             throw new BugManager\ValidationException('Invalid milestone, must be a PEAR2\BugManager\Milestone object');
         }
+        Issue::addEscaper($this->getEscaper());
         $sql = 'SELECT COUNT(*) as count
             FROM bugmanager_roadmap r
             WHERE
@@ -663,6 +687,20 @@
                                          AND revision="' . $id . '"');
         }
         $test->close();
+        Issue::removeEscaper($this->escaper);
+        $this->query('BEGIN');
+        $attachment->revision = $id;
+        $comment = $attachment->bug->newComment($attachment->commentText);
+        try {
+            $this->update($attachment->bug);
+            $attachment->commentid = $comment->id;
+        } catch (\Exception $e) {
+            $this->query('ROLLBACK');
+            throw new BugManager\UnexpectedValueException('Could not create attachment comment for issue #' .
+                                                          $attachment->bug->id . ', attachment "' . $attachment->name .
+                                                          '": ' . $e->getMessage());
+        }
+        Issue::addEscaper($this->escaper);
         if (!$this->query('INSERT INTO bugmanager_patchtracker
                                   (bug_id, comment_id, name, revision, recordversion)
                                   VALUES(' . $attachment->bug->id . ',
@@ -671,10 +709,14 @@
                                     "' . $id . '",
                                     "' . self::PATCHTRACKERRECORDVERSION . '"
                                     )')) {
+            $error = $this->mysqli->error;
+            $this->query('ROLLBACK');
             Issue::removeEscaper($this->escaper);
             throw new BugManager\UnexpectedValueException('Could not get unique attachment file name for issue #' .
-                $attachment->bug->id . ', attachment "'. $attachment->name . '"');
+                $attachment->bug->id . ', attachment "'. $attachment->name . '": ' .
+                $error);
         }
+        $this->query('COMMIT');
         Issue::removeEscaper($this->escaper);
         $attachment->revision = $id;
         $attachment->markAsOld();
@@ -685,11 +727,15 @@
         if (!$attachment->revision) {
             return;
         }
-        Issue::addEscaper($this->escaper);
+        Issue::addEscaper($this->getEscaper());
         $test = $this->query('SELECT revision FROM bugmanager_patchtracker
                              WHERE bug_id=' . $attachment->bug->id . '
                              AND name=' . $attachment->name . '
                              AND revision=' . $attachment->revision);
+        if (!$test) {
+            Issue::removeEscaper($this->escaper);
+            throw new \Exception('Error: ' . $this->mysqli->error);
+        }
         if (!$test->num_rows) {
             $test->close();
             Issue::removeEscaper($this->escaper);
@@ -705,7 +751,7 @@

     function obsoletePatch(BugManager\Attachment $attachment, $obsoletename, $obsoleterevision)
     {
-        Issue::addEscaper($this->escaper);
+        Issue::addEscaper($this->getEscaper());
         $this->query('INSERT INTO bugmanager_obsoletes_patches
                 (bug_id, name, revision, obsolete_name, obsolete_revision, recordversion)
             VALUES(' . $attachment->bug->id . ',
@@ -719,7 +765,7 @@

     function addMilestone(BugManager\Milestone $milestone)
     {
-        Issue::addEscaper($this->escaper);
+        Issue::addEscaper($this->getEscaper());
         $this->query('INSERT INTO bugmanager_roadmap
                              (package, roadmap_version, releasedate, description, released, recordversion)
                     VALUES(
@@ -736,7 +782,7 @@

     function linkMilestoneToIssues(BugManager\Milestone $milestone)
     {
-        Issue::addEscaper($this->escaper);
+        Issue::addEscaper($this->getEscaper());
         $this->query('DELETE FROM bugmanager_roadmap_link WHERE
                              roadmap_id=' . $milestone->id);
         foreach ($milestone->issues as $issue) {
@@ -753,7 +799,7 @@

     function updateMilestone(BugManager\Milestone  $milestone)
     {
-        Issue::addEscaper($this->escaper);
+        Issue::addEscaper($this->getEscaper());
         $this->mysqli->query('UPDATE bugmanager_roadmap
                              SET
                     package=' . $milestone->package . ',

Modified: pear2/BugManager/trunk/src/BugManager/Site/PEAR/ActorManager.php
===================================================================
--- pear2/BugManager/trunk/src/BugManager/Site/PEAR/ActorManager.php	2010-09-27 03:03:21 UTC (rev 303776)
+++ pear2/BugManager/trunk/src/BugManager/Site/PEAR/ActorManager.php	2010-09-27 03:18:41 UTC (rev 303777)
@@ -90,7 +90,7 @@
             $ret->karma = Actor::ADMIN;
         }
         $karma = $this->mysqli->query('SELECT * FROM karma
-                                      WHERE user="' . $info['handle'] . '"');
+                                      WHERE user="' . $this->esc($info['handle']) . '"');
         while ($res = $karma->fetch_assoc()) {
             if ($res['level'] == 'pear.admin') {
                 $ret->karma = Actor::ADMIN;
@@ -171,6 +171,9 @@
     function loggedinUser($except = false)
     {
         if (null === self::$loggedinUser) {
+            if (!session_id()) {
+                session_start();
+            }
             if (isset($_SESSION['bugmanager_user'])) {
                 self::$loggedinUser = $this->retrieve($_SESSION['bugmanager_user']);
             }

Modified: pear2/BugManager/trunk/www/pearworm/source/class/pearworm/view/IssueEdit.js
===================================================================
--- pear2/BugManager/trunk/www/pearworm/source/class/pearworm/view/IssueEdit.js	2010-09-27 03:03:21 UTC (rev 303776)
+++ pear2/BugManager/trunk/www/pearworm/source/class/pearworm/view/IssueEdit.js	2010-09-27 03:18:41 UTC (rev 303777)
@@ -40,7 +40,7 @@
       this._emailfield.set({
             required: false,
             visibility: "excluded",
-            value: ""
+            value: "[email protected]"
           });
     },
     handleLogout: function()
@@ -370,11 +370,16 @@
     _uploadform: null,
     _file: null,
     _emailfield: null,
+    _uploadfield: null,
+    _uploadsubmit: null,
+    _oldpatches: null,
+    _patchname: null,
     getAddPatchForm: function()
     {
       var container = new qx.ui.container.Composite(new qx.ui.layout.VBox(5));
       var mainform = new qx.ui.form.Form();
       var form = new uploadwidget.UploadForm('uploadFrm', 'uploadattachment.php');
+      this._uploadform = form;
       var oldpatchesdata = this._issue.getObsoleteablePatches(),
           oldpatches = new qx.ui.form.List().set({
             selectionMode: "additive",
@@ -390,8 +395,15 @@
           emailfield = new qx.ui.form.TextField().set({
             required: true
           }),
-          file = new uploadwidget.UploadField('uploadfile', 'Upload Attachment',
-                                              'pearworm/document-send.png');
+          file = new uploadwidget.UploadField('uploadfile', 'Choose Attachment',
+                                              'pearworm/document-send.png'),
+          submitbutton = new qx.ui.form.Button("Save Attachment").set({
+            enabled: false,
+            allowGrowX: false
+          });
+      this._uploadsubmit = submitbutton;
+      this._oldpatches = oldpatches;
+      this._patchname = patchname;
       form.setLayout(new qx.ui.layout.VBox(5));
       form.add(file);

@@ -408,7 +420,11 @@

       this._emailfield = emailfield;
       if (pearworm.LoginWindow.canEditBugs()) {
-        this.handleLogin();
+        this._emailfield.set({
+          required: false,
+          visibility: "excluded",
+          value: "[email protected]"
+        });
       }
       mainform.add(emailfield, "Your Email Address", qx.util.Validate.email(), "newuseremail");
       mainform.add(patchname, "Attachment Name");
@@ -418,33 +434,39 @@

       container.add(new qx.ui.form.renderer.Single(mainform));
       container.add(form);
+      container.add(submitbutton);

-      file.addListener('changeFileName',function(e){
-        if(e.getData()!='') {
-          form.setParameter("name", patchname.getValue());
-          var sel = oldpatches.getSelection();
-          for (var i = 0; i < sel.getLength(); i++) {
-            form.setParameter("oldpatches[" + i + "]", sel.getItem(i).getName() + "-" + sel.getItem(i).getRevision());
-          }
-          if (mainform.validate()) {
-            form.send();
-          }
+      file.addListener("changeFileName", this.__checkEnableSubmit, this);
+      submitbutton.addListener("execute",function() {
+        form.setParameter("name", this._patchname.getValue());
+        form.setParameter("bug", this._issue.getId());
+        var sel = this._oldpatches.getSelection();
+        for (var i = 0; i < sel.length; i++) {
+          var model = sel[i].getModel();
+          form.setParameter("oldpatches[" + i + "]", model.getName() + "-" + model.getRevision());
         }
-      });
-      var callback = function() {
-        if (mainform.validate() && file.getFileName() != '') {
+        if (mainform.validate()) {
           form.send();
         }
-      };
-      patchname.addListener("changeValue", callback);
-      emailfield.addListener("changeValue", callback);
+      }, this);
+      patchname.addListener("changeValue", this.__checkEnableSubmit, this);
+      emailfield.addListener("changeValue", this.__checkEnableSubmit, this);

       form.addListener('completed', this.__handlePatchUpload, this);
       return container;
     },
+    __checkEnableSubmit: function()
+    {
+      var f = this._file.getFileName(), g = this._patchname.getValue();
+      if (this._file.getFileName() && this._patchname.getValue() && (!this._emailfield.getRequired() ||
+          this._emailfield.getValue())) {
+        this._uploadsubmit.setEnabled(true);
+      } else {
+        this._uploadsubmit.setEnabled(false);
+      }
+    },
     __handlePatchUpload: function()
     {
-      this._file.setFieldValue('');
       var response = qx.util.Json.parse(this._uploadform.getIframeTextContent(), false);
       if (response.error) {
         alert("Invalid upload ["+response.error+"], please try again");
@@ -590,13 +612,13 @@
       this._editpage = editpage;
       choices.add(this._commentpage = commentpage);
       choices.add(this._addpatchpage = addpatchpage);
-      if (this.getView() == "add") {
-        choices.setSelection([addpatchpage]);
-      }
       this.displayEditOrAddCommentPage();
       if (this.getView() == "edit") {
         choices.setSelection([this.getKarmaEditPage()]);
       }
+      if (this.getView() == "add") {
+        choices.setSelection([addpatchpage]);
+      }

       choices.addListener("changeSelection", this.tabListener, this);


Modified: pear2/BugManager/trunk/www/pearworm/source/uploadattachment.php
===================================================================
--- pear2/BugManager/trunk/www/pearworm/source/uploadattachment.php	2010-09-27 03:03:21 UTC (rev 303776)
+++ pear2/BugManager/trunk/www/pearworm/source/uploadattachment.php	2010-09-27 03:18:41 UTC (rev 303777)
@@ -7,11 +7,15 @@
 }

 // Set the site we'll be using
+use PEAR2\BugManager\Issue, PEAR2\BugManager\Attachment;
 PEAR2\BugManager\Main::setSite($site);

-set_error_handler(function($n, $e) {
+set_error_handler(function($n, $e, $f, $l) {
+    if (0 === error_reporting()) {
+        return;
+    }
     $output = json_encode(array(
-        'error' => $e
+        'error' => $e . ' in ' . $f . ' on ' . $l
         ));
     header('Content-type: text/plain');
     header('Content-length: ' . strlen($output));
@@ -20,18 +24,23 @@
 });

 try {
+    if (!isset($_POST) || !isset($_POST['bug'])) {
+        throw new Exception("cannot upload");
+    }
     $bug = new Issue();
     $bug->id = $_POST['bug'];
     $bug->retrieve();
     $attach = new Attachment();
-    $attach->attach('patch', $_FILES);
-    $output = $attach->toJson();
+    $attach->bug = $bug;
+    $attach->name = $_POST['name'];
+    $attach->attach('uploadfile', $_FILES);
+    $output = json_encode($attach->toJson());
     header('Content-type: text/plain');
     header('Content-length: ' . strlen($output));
     echo $output;
 } catch (Exception $e) {
     $output = json_encode(array(
-        'error' => 'Invalid input'
+        'error' => 'Invalid input ' . $e->getMessage()
                                ));
     header('Content-type: text/plain');
     header('Content-length: ' . strlen($output));