PEPr
[ class tree: PEPr ] [ index: PEPr ] [ all elements ]

Source for file pepr-proposal.php

Documentation is available at pepr-proposal.php

  1. <?php
  2. /**
  3.  * Establishes the procedures, objects and variables used throughout PEPr.
  4.  *
  5.  * The <var>$proposalStatiMap</var> is defined here.
  6.  *
  7.  * NOTE: Proposal constants are defined in pearweb/include/pear-config.php.
  8.  *
  9.  * This source file is subject to version 3.0 of the PHP license,
  10.  * that is bundled with this package in the file LICENSE, and is
  11.  * available through the world-wide-web at the following URI:
  12.  * http://www.php.net/license/3_0.txt.
  13.  * If you did not receive a copy of the PHP license and are unable to
  14.  * obtain it through the world-wide-web, please send a note to
  15.  * license@php.net so we can mail you a copy immediately.
  16.  *
  17.  * @category  pearweb
  18.  * @package   PEPr
  19.  * @author    Tobias Schlitt <toby@php.net>
  20.  * @author    Daniel Convissor <danielc@php.net>
  21.  * @copyright Copyright (c) 1997-2005 The PHP Group
  22.  * @license   http://www.php.net/license/3_0.txt  PHP License
  23.  * @version   $Id: pepr-proposal.php 309391 2011-03-18 15:37:50Z till $
  24.  */
  25.  
  26. global $proposalStatiMap;
  27. $proposalStatiMap = array(
  28.                           'draft'    => 'Draft',
  29.                           'proposal' => 'Proposed',
  30.                           'vote'     => 'Called for Votes',
  31.                           'finished' => 'Finished'
  32.                           );
  33.  
  34.  
  35. class proposal
  36. {
  37.     var $id;
  38.     var $pkg_category;
  39.     var $pkg_name;
  40.     var $pkg_license;
  41.     var $pkg_description;
  42.     var $pkg_deps;
  43.     var $draft_date;
  44.     var $proposal_date;
  45.     var $vote_date;
  46.     var $longened_date;
  47.     var $status = 'draft';
  48.     var $user_handle;
  49.     var $links;
  50.     var $votes;
  51.     var $markup;
  52.  
  53.     function __construct($dbhResArr)
  54.     {
  55.         $this->fromArray($dbhResArr);
  56.     }
  57.  
  58.     function fromArray($dbhResArr)
  59.     {
  60.         if (!is_array($dbhResArr)) {
  61.             return false;
  62.         }
  63.         foreach ($dbhResArr as $name => $value{
  64.             if ($name == 'pkg_describtion'{
  65.                 $name 'pkg_description';
  66.             }
  67.             $this->$name $value;
  68.         }
  69.         return true;
  70.     }
  71.  
  72.     function toRSSArray ($full = false)
  73.     {
  74.         return array(
  75.             'title'         => 'PEPr Proposal ['.$this->id.']: '.$this->pkg_category.'::'.$this->pkg_name,
  76.             'link'          => 'http://' . PEAR_CHANNELNAME . '/pepr/pepr-proposal-show.php?id='$this->id,
  77.             'desc'          => '
  78. Proposed package:        '.$this->pkg_category.'::'.$this->pkg_name.'<br />
  79. Proposer:                '.user_link($this->user_handletrue).'<br />
  80.             'date'          => $this->draft_date
  81.          );
  82.     }
  83.  
  84.     function getParsedDescription()
  85.     {
  86.         if (empty($this->pkg_description)) {
  87.             return '';
  88.         }
  89.         // Switching markup types
  90.         switch ($this->markup{
  91.             case 'wiki':
  92.                include_once 'Text/Wiki.php';
  93.                $wiki = new Text_Wiki();
  94.                $wiki->disableRule('wikilink');
  95.                $description $wiki->transform($this->pkg_description);
  96.                break;
  97.             case 'bbcode':
  98.             default:
  99.                include_once 'HTML/BBCodeParser.php';
  100.                $bbparser = new HTML_BBCodeParser(array('filters' => 'Basic,Images,Links,Lists,Extended'));
  101.                $description $bbparser->qparse(nl2br(htmlentities($this->pkg_description)));
  102.                break;
  103.         }
  104.         return $description;
  105.     }
  106.  
  107.     function fromOld($id)
  108.     {
  109.         global $dbh;
  110.         if ($id === null{
  111.             return null;
  112.         }
  113.  
  114.         if (!is_numeric($id)) {
  115.             return new proposal(array());
  116.         }
  117.  
  118.         $id  = (int)$id;
  119.         $sql "SELECT pkg_name, pkg_category, pkg_license, pkg_describtion, pkg_deps
  120.                  FROM package_proposals WHERE id = ".$id;
  121.         $res $dbh->getRow($sqlnullDB_FETCHMODE_ASSOC);
  122.         if (DB::isError($res)) {
  123.             return new proposal(array());
  124.         }
  125.  
  126.         if (!$res{
  127.             return new proposal(array());
  128.         }
  129.  
  130.         return new proposal($res);
  131.     }
  132.  
  133.     /**
  134.      * Look up proposal information based on the proposal ID number
  135.      *
  136.      * @param object $dbh  the current DB object
  137.      * @param int    $id   the ID number of the proposal being looked for
  138.      *
  139.      * @return object  new proposal object.  false if the $id provided is
  140.      *                  not numeric.  null if the $id doesn't refer to
  141.      *                  an actual proposal.
  142.      *
  143.      * @access public
  144.      */
  145.     function get(&$dbh$id)
  146.     {
  147.         if (!is_numeric($id)) {
  148.             $res = false;
  149.             return $res;
  150.         }
  151.         $id  = (int)$id;
  152.         $sql "SELECT *, UNIX_TIMESTAMP(draft_date) as draft_date,
  153.                         UNIX_TIMESTAMP(proposal_date) as proposal_date,
  154.                         UNIX_TIMESTAMP(vote_date) as vote_date,
  155.                         UNIX_TIMESTAMP(longened_date) as longened_date
  156.                  FROM package_proposals WHERE id = ".$id;
  157.         $res $dbh->getRow($sqlnullDB_FETCHMODE_ASSOC);
  158.         if (DB::isError($res)) {
  159.             return $res;
  160.         }
  161.         if (!$res{
  162.             return $res;
  163.         }
  164.         $t = new proposal($res);
  165.         return $t;
  166.     }
  167.  
  168.     function getRecent($dbh$n{
  169. //'proposed'
  170.        return self::getAll($dbhnull$n'proposal_date DESC');
  171.     }
  172.  
  173.     /**
  174.      * Receive a complete bunch of proposals.
  175.      *
  176.      * @param object $dbh  the current DB object
  177.      * @param string $status  the of the proposals to select
  178.      * @param int    $limit  limit the number of proposals to receive
  179.      * @param string $order  an SQL expression used by the "ORDER BY" statement
  180.      *
  181.      * @return array   an array of proposal objects (maybe with 0 elements,
  182.      *                  if no proposals received)
  183.      *
  184.      * @access public
  185.      */
  186.     function &getAll(&$dbh$status = null$limit = null$order = null)
  187.     {
  188.         $sql "SELECT *, UNIX_TIMESTAMP(draft_date) as draft_date,
  189.                         UNIX_TIMESTAMP(proposal_date) as proposal_date,
  190.                         UNIX_TIMESTAMP(vote_date) as vote_date,
  191.                         UNIX_TIMESTAMP(longened_date) as longened_date
  192.                     FROM package_proposals";
  193.         if (!empty($status)) {
  194.             $sql .= " WHERE status = '".$status."'";
  195.         }
  196.         if (!isset($order)) {
  197.             $sql .= " ORDER BY status ASC, draft_date DESC";
  198.         else {
  199.             $sql .= " ORDER BY ".$order;
  200.         }
  201.         if (!empty($limit)) {
  202.             $sql .= " LIMIT $limit";
  203.         }
  204.         $res $dbh->query($sql);
  205.         if (DB::isError($res)) {
  206.             return $res;
  207.         }
  208.         $result = array();
  209.         while ($set $res->fetchRow(DB_FETCHMODE_ASSOC)) {
  210.             $result[$set['id']] = new proposal($set);
  211.         }
  212.         return $result;
  213.     }
  214.  
  215.     function &search($searchString)
  216.     {
  217.         global $dbh;
  218.         $replacers = array(
  219.             '/%/''/_/''/ /''/\*/''/\?/');
  220.         $replacements = array(
  221.             '\%''\_''%''%''_');
  222.         $searchString "%".preg_replace($replacers$replacements$searchString)."%";
  223.  
  224.         $sql "SELECT *, UNIX_TIMESTAMP(draft_date) as draft_date,
  225.                        UNIX_TIMESTAMP(proposal_date) as proposal_date,
  226.                        UNIX_TIMESTAMP(vote_date) as vote_date,
  227.                        UNIX_TIMESTAMP(longened_date) as longened_date
  228.                 FROM package_proposals
  229.                 WHERE pkg_describtion LIKE ".$dbh->quoteSmart($searchString)."
  230.                       OR pkg_name LIKE ".$dbh->quoteSmart($searchString)."
  231.                       OR pkg_category LIKE ".$dbh->quoteSmart($searchString)."
  232.                 ORDER BY status ASC, draft_date DESC";
  233.         $res $dbh->query($sql);
  234.         if (DB::isError($res)) {
  235.             return $res;
  236.         }
  237.         $result = array();
  238.         while ($set $res->fetchRow(DB_FETCHMODE_ASSOC)) {
  239.             $result[$set['id']] = new proposal($set);
  240.         }
  241.         return $result;
  242.     }
  243.  
  244.     function getLinks(&$dbh)
  245.     {
  246.         if (empty($this->id)) {
  247.             return PEAR::raiseError("Not initialized");
  248.         }
  249.         $this->links = ppLink::getAll($dbh$this->id);
  250.         return true;
  251.     }
  252.  
  253.     function getVotes(&$dbh)
  254.     {
  255.         if (empty($this->id)) {
  256.             return PEAR::raiseError("Not initialized");
  257.         }
  258.         $this->votes = ppVote::getAll($dbh$this->id);
  259.         return true;
  260.     }
  261.  
  262.     function mayRePropose($handle$checkid = false)
  263.     {
  264.         global $dbh;
  265.         if (!$this->id{
  266.             $this->id = 0;
  267.         }
  268.  
  269.         if ($checkid{
  270.             $test $dbh->getOne('SELECT id FROM package_proposals WHERE pkg_category = ?
  271.                 AND pkg_name = ? AND user_handle = ? AND id <> ?'array($this->pkg_category,
  272.                 $this->pkg_name$this->user_handle$this->id));
  273.             $next $dbh->getAll('SELECT id, status FROM package_proposals WHERE pkg_category = ?
  274.                     AND pkg_name = ? AND user_handle = ? AND id <> ?'array($this->pkg_category,
  275.                     $this->pkg_name$this->user_handle$this->id));
  276.         else {
  277.             $test $dbh->getOne('SELECT id FROM package_proposals WHERE pkg_category = ?
  278.                 AND pkg_name = ? AND user_handle = ?'array($this->pkg_category,
  279.                 $this->pkg_name$this->user_handle));
  280.             $next $dbh->getAll('SELECT id, status FROM package_proposals WHERE pkg_category = ?
  281.                     AND pkg_name = ? AND user_handle = ?'array($this->pkg_category,
  282.                     $this->pkg_name$this->user_handle));
  283.         }
  284.         if ($test{
  285.             foreach ($next as $p{
  286.                 if ($p[1!= 'finished'{
  287.                     return false;
  288.                 }
  289.                 $votes ppVote::getSum($dbh$p[0]);
  290.                 if ($votes['all'> 5{
  291.                     // proposal was accepted, can't repropose
  292.                     return false;
  293.                 }
  294.             }
  295.             return true;
  296.         }
  297.         return true;
  298.     }
  299.  
  300.     function store($dbh)
  301.     {
  302.         if (isset($this->id)) {
  303.             $inf $dbh->getAll('SELECT pkg_name, pkg_category FROM package_proposals
  304.                 WHERE id = ?'array($this->id));
  305.             if ($inf[0!= $this->pkg_name || $inf[1!= $this->pkg_category{
  306.                 if (!$this->mayRePropose($this->user_handletrue)) {
  307.                     return PEAR::raiseError('A proposal with that Category -'
  308.                             . ' Name combination already exists.');
  309.                 }
  310.             }
  311.             $sql "UPDATE package_proposals SET
  312.                     pkg_category = ".$dbh->quoteSmart($this->pkg_category).",
  313.                     pkg_name = ".$dbh->quoteSmart($this->pkg_name).",
  314.                     pkg_license = ".$dbh->quoteSmart($this->pkg_license).",
  315.                     pkg_describtion = ".$dbh->quoteSmart($this->pkg_description).",
  316.                     pkg_deps = ".$dbh->quoteSmart($this->pkg_deps).",
  317.                     draft_date = FROM_UNIXTIME({$this->draft_date}),
  318.                     proposal_date = FROM_UNIXTIME({$this->proposal_date}),
  319.                     vote_date = FROM_UNIXTIME({$this->vote_date}),
  320.                     longened_date = FROM_UNIXTIME({$this->longened_date}),
  321.                     status = ".$dbh->quoteSmart($this->status).",
  322.                     user_handle = ".$dbh->quoteSmart($this->user_handle).",
  323.                     markup = ".$dbh->quoteSmart($this->markup)."
  324.                     WHERE id = ".$this->id;
  325.             $dbh->pushErrorHandling(PEAR_ERROR_RETURN);
  326.             $res $dbh->query($sql);
  327.             $dbh->popErrorHandling();
  328.             if (DB::isError($res)) {
  329.                 if ($res->getCode(== DB_ERROR_CONSTRAINT{
  330.                     return PEAR::raiseError('A proposal with that Category -'
  331.                             . ' Name combination already exists.',
  332.                             $res->getCode()nullnull$res->getUserInfo());
  333.                 } else {
  334.                     return PEAR::raiseError($res->getMessage(),
  335.                                             $res->getCode()nullnull,
  336.                                             $res->getUserInfo());
  337.                 }
  338.             }
  339.         } else {
  340.             if ($dbh->getOne('SELECT id FROM package_proposals WHERE pkg_category = ?
  341.                     AND pkg_name = ? AND user_handle <> ?'array($this->pkg_category,
  342.                     $this->pkg_name$this->user_handle))) {
  343.                 return PEAR::raiseError('A proposal with that Category -'
  344.                         . ' Name combination already exists.');
  345.             }
  346.             if (!$this->mayRePropose($this->user_handle)) {
  347.                 // proposal was accepted, can't repropose
  348.                 return PEAR::raiseError('A non-rejected proposal with that Category -'
  349.                         . ' Name combination already exists.');
  350.             }
  351.             $sql = "INSERT INTO package_proposals (pkg_category, pkg_name, pkg_license, pkg_describtion,
  352.                         pkg_deps, draft_date, status, user_handle, markup) VALUES (
  353.                         ".$dbh->quoteSmart($this->pkg_category).",
  354.                         ".$dbh->quoteSmart($this->pkg_name).",
  355.                         ".$dbh->quoteSmart($this->pkg_license).",
  356.                         ".$dbh->quoteSmart($this->pkg_description).",
  357.                         ".$dbh->quoteSmart($this->pkg_deps).",
  358.                         FROM_UNIXTIME(".time()."),
  359.                         ".$dbh->quoteSmart($this->status).",
  360.                         ".$dbh->quoteSmart($this->user_handle).",
  361.                         ".$dbh->quoteSmart($this->markup).")";
  362.             $dbh->pushErrorHandling(PEAR_ERROR_RETURN);
  363.             $res $dbh->query($sql);
  364.             $dbh->popErrorHandling();
  365.             if (DB::isError($res)) {
  366.                 if ($res->getCode(== DB_ERROR_CONSTRAINT{
  367.                     return PEAR::raiseError('A proposal with that Catetory -'
  368.                             . ' Name combination already exists.',
  369.                             $res->getCode()nullnull$res->getUserInfo());
  370.                 } else {
  371.                     return PEAR::raiseError($res->getMessage(),
  372.                                             $res->getCode()nullnull,
  373.                                             $res->getUserInfo());
  374.                 }
  375.             }
  376.             $this->id = mysqli_insert_id($dbh->connection);
  377.         }
  378.         ppLink::deleteAll($dbh, $this->id);
  379.         if (isset($this->links&& count($this->links)) {
  380.             foreach ($this->links as $link{
  381.                 if (!empty($link->url)) {
  382.                     $res = $link->store($dbh$this->id);
  383.                     if (DB::isError($res)) {
  384.                         return $res;
  385.                     }
  386.                 }
  387.             }
  388.         }
  389.         if (!empty($this->comment)) {
  390.             $this->comment->store($dbh$this->id);
  391.             unset($this->comment);
  392.         }
  393.         return true;
  394.     }
  395.  
  396.     function addVote($dbh, $vote)
  397.     {
  398.         if (!empty($this->votes[$vote->user_handle])) {
  399.             return PEAR::raiseError("You already voted!");
  400.         }
  401.         $vote->pkg_propop_id = $this->id;
  402.         $this->votes[$vote->user_handle$vote;
  403.         $vote->store($dbh$this->id);
  404.         return true;
  405.     }
  406.  
  407.     function addComment($comment, $table = 'package_proposal_changelog')
  408.     {
  409.         global $auth_user;
  410.  
  411.         $commentData = array("pkg_prop_id" => $this->id,
  412.                              "user_handle" => $auth_user->handle,
  413.                              "comment"     => $comment);
  414.         $comment = new ppComment$commentData$table );
  415.         $comment->store($this->id);
  416.         return true;
  417.     }
  418.  
  419.     function addLink($link)
  420.     {
  421.         $link = new ppLink($link);
  422.         $link->pkg_prop_id = $this->id;
  423.         $this->links[$link;
  424.         return true;
  425.     }
  426.  
  427.     function isOwner($handle)
  428.     {
  429.         if (strtolower($this->user_handle!= strtolower($handle)) {
  430.             return false;
  431.         }
  432.         return true;
  433.     }
  434.  
  435.     function mayEdit($handle = '')
  436.     {
  437.         global $dbh, $karma;
  438.  
  439.         if (empty($karma)) {
  440.             $karma = new Damblan_Karma($dbh);
  441.         }
  442.  
  443.         switch ($this->status{
  444.             case 'draft':
  445.             case 'proposal':
  446.                 if ($this->isOwner($handle|| $karma->has($handle'pear.pepr.admin')) {
  447.                     return true;
  448.                 }
  449.               break;
  450.             default:
  451.                 if (!$this->isOwner($handle&& $karma->has($handle'pear.pepr.admin')) {
  452.                     return true;
  453.                 }
  454.                 break;
  455.         }
  456.         return false;
  457.     }
  458.  
  459.     /**
  460.      * Determine if the current user can vote on the current proposal
  461.      *
  462.      * Rules:
  463.      *   + Proposal must be in the "Called for Votes" phase.
  464.      *   + User must be logged in.
  465.      *   + User must be a full-featured PEAR developer.
  466.      *   + Only one vote can be cast.
  467.      *   + Proposers can't vote on their own package, though can for RFC's.
  468.      *
  469.      * @param object $dbh         the current DB object
  470.      * @param string $userHandle  the user's handle
  471.      *
  472.      * @return bool
  473.      *
  474.      * @access public
  475.      */
  476.     function mayVote(&$dbh, $userHandle)
  477.     {
  478.         global $karma;
  479.  
  480.         if (empty($karma)) {
  481.             $karma = new Damblan_Karma($dbh);
  482.         }
  483.  
  484.         if ($this->getStatus(== 'vote' &&
  485.             $karma->has($userHandle'pear.dev'&&
  486.             !ppVote::hasVoted($dbh$userHandle$this->id&&
  487.             (!$this->isOwner($userHandle||
  488.              ($this->isOwner($userHandle&&
  489.               $this->pkg_category == 'RFC')))
  490.         {
  491.             return true;
  492.         }
  493.  
  494.         return false;
  495.     }
  496.  
  497.     function getStatus($humanReadable = false)
  498.     {
  499.         if ($humanReadable) {
  500.             return $GLOBALS['proposalStatiMap'][$this->status];
  501.         }
  502.         return $this->status;
  503.     }
  504.  
  505.     /**
  506.      * Answers the question "Is this proposal $operator than $status?"
  507.      *
  508.      * @param string $operator  the operator (<, <=, ==, >=, >, !=)
  509.      * @param string $status    the status ('draft', 'vote', 'finished', etc)
  510.      *
  511.      * @return bool
  512.      */
  513.     function compareStatus($operator, $status)
  514.     {
  515.         $num = array(
  516.             'draft'    => 1,
  517.             'proposal' => 2,
  518.             'vote'     => 3,
  519.             'finished' => 4,
  520.         );
  521.         switch ($operator) {
  522.             case '<':
  523.                 return ($num[$this->status$num[$status]);
  524.             case '<=':
  525.                 return ($num[$this->status<= $num[$status]);
  526.             case '==':
  527.                 return ($num[$this->status== $num[$status]);
  528.             case '>=':
  529.                 return ($num[$this->status>= $num[$status]);
  530.             case '>':
  531.                 return ($num[$this->status$num[$status]);
  532.             case '!=':
  533.                 return ($num[$this->status!= $num[$status]);
  534.             default:
  535.                 PEAR::raiseError('Invalid $operator passed to compareStatus()');
  536.         }
  537.     }
  538.  
  539.     function isEditable()
  540.     {
  541.         switch ($this->status{
  542.         case 'draft':
  543.         case 'proposal'return true;
  544.         }
  545.         return false;
  546.     }
  547.  
  548.     function checkTimeline()
  549.     {
  550.         switch ($this->status{
  551.         case 'draft':
  552.             return true;
  553.         case 'proposal':
  554.             if (($this->proposal_date + PROPOSAL_STATUS_PROPOSAL_TIMELINE< time()) {
  555.                 return true;
  556.             }
  557.             return (int)($this->proposal_date + PROPOSAL_STATUS_PROPOSAL_TIMELINE);
  558.         case 'vote':
  559.             if (!empty($this->longened_date)) {
  560.                 if (($this->longened_date + PROPOSAL_STATUS_VOTE_TIMELINE> time()) {
  561.                     return (int)($this->longened_date + PROPOSAL_STATUS_VOTE_TIMELINE);
  562.                 }
  563.             } else {
  564.                 if (($this->vote_date + PROPOSAL_STATUS_VOTE_TIMELINE> time()) {
  565.                     return (int)($this->vote_date + PROPOSAL_STATUS_VOTE_TIMELINE);
  566.                 }
  567.             }
  568.             return false;
  569.         }
  570.     }
  571.  
  572.     function delete(&$dbh)
  573.     {
  574.         if (empty($this->id)) {
  575.             return PEAR::raiseError("Proposal does not exist!");
  576.         }
  577.         $sql = "DELETE FROM package_proposals WHERE id = ".$this->id;
  578.         $res $dbh->query($sql);
  579.         if (DB::isError($res)) {
  580.             return $res;
  581.         }
  582.         $sql = "DELETE FROM package_proposal_votes WHERE pkg_prop_id = ".$this->id;
  583.         $res $dbh->query($sql);
  584.         if (DB::isError($res)) {
  585.             return $res;
  586.         }
  587.         $sql = "DELETE FROM package_proposal_links WHERE pkg_prop_id = ".$this->id;
  588.         $res $dbh->query($sql);
  589.         if (DB::isError($res)) {
  590.             return $res;
  591.         }
  592.         $sql = "DELETE FROM package_proposal_changelog WHERE pkg_prop_id = ".$this->id;
  593.         $res $dbh->query($sql);
  594.         if (DB::isError($res)) {
  595.             return $res;
  596.         }
  597.         $sql = "DELETE FROM package_proposal_comments WHERE pkg_prop_id = ".$this->id;
  598.         $res $dbh->query($sql);
  599.         if (DB::isError($res)) {
  600.             return $res;
  601.         }
  602.         return true;
  603.     }
  604.  
  605.     function sendActionEmail($event, $userType, $user_handle = null,
  606.                              $comment = '')
  607.     {
  608.         global $dbh, $karma, $auth_user;
  609.  
  610.         if (empty($karma)) {
  611.             $karma = new Damblan_Karma($dbh);
  612.         }
  613.  
  614.         require 'pepr/pepr-emails.php';
  615.         $email = $proposalEmailTexts[$event];
  616.         if (empty($email)) {
  617.             return PEAR::raiseError("Email template for $event not found");
  618.         }
  619.         switch ($userType) {
  620.         case 'admin':
  621.             $prefix = "[ADMIN]";
  622.             break;
  623.         case 'mixed':
  624.             if ($karma->has($user_handle"pear.pepr.admin"&& ($this->user_handle != $user_handle)) {
  625.                 $prefix = "[ADMIN]";
  626.             } else {
  627.                 $prefix = "";
  628.             }
  629.             break;
  630.         default:
  631.             $prefix = "";
  632.         }
  633.         $prefix = PROPOSAL_EMAIL_PREFIX . $prefix . " ";
  634.         include_once 'pear-database-user.php';
  635.         $actorinfo = user::info($user_handle);
  636.         $ownerinfo = user::info($this->user_handle);
  637.         $this->getVotes($dbh);
  638.         $vote @$this->votes[$user_handle];
  639.         if (isset($vote)) {
  640.             $vote->value = ($vote->value > 0"+".$vote->value : $vote->value;
  641.             if ($vote->is_conditional{
  642.                 $vote_conditional = "\n\nThis vote is conditional. The condition is:\n\n".$vote->comment;
  643.             } elseif ($vote->comment{
  644.                 $comment = "\n\nComment:\n\n" . $vote->comment;
  645.             }
  646.  
  647.             $vote_url = "http://" . PEAR_CHANNELNAME . "/pepr/pepr-vote-show.php?id=".$this->id."&handle=".$user_handle;
  648.         }
  649.  
  650.         if ($event == 'change_status_finished') {
  651.             $proposalVotesSum = ppVote::getSum($dbh, $this->id);
  652.  
  653.             $vote_result  'Sum of Votes: ' $proposalVotesSum['all'];
  654.             $vote_result .= ' (' $proposalVotesSum['conditional']
  655.                           . ' conditional)';
  656.  
  657.             if ($proposalVotesSum['all'>= 5{
  658.                 $vote_result .= "\nResult:       This proposal was accepted";
  659.             } else {
  660.                 $vote_result .= "\nResult:       This proposal was rejected";
  661.             }
  662.         }
  663.  
  664.         $proposal_url = "http://" . PEAR_CHANNELNAME . "/pepr/pepr-proposal-show.php?id=".$this->id;
  665.         $end_voting_time (@$this->longened_date > 0$this->longened_date + PROPOSAL_STATUS_VOTE_TIMELINE : @$this->vote_date + PROPOSAL_STATUS_VOTE_TIMELINE;
  666.  
  667.         if ($event == 'proposal_comment' && $user_handle == $this->user_handle{
  668.             $email['to'] = $email['to']['owner'];
  669.         } else {
  670.             if (!isset($user_handle)) {
  671.                 $email['to'] = $email['to']['pearweb'];
  672.             } else if ($karma->has($user_handle"pear.pepr.admin")) {
  673.                 $email['to'] = $email['to']['admin'];
  674.             } else {
  675.                 $email['to'] = $email['to']['user'];
  676.             }
  677.         }
  678.  
  679.         $email['subject'] = $prefix . $email['subject'];
  680.         $replace = array(
  681.                          "/\{pkg_category\}/",
  682.                          "/\{pkg_name\}/",
  683.                          "/\{owner_name\}/",
  684.                          "/\{owner_email\}/",
  685.                          "/\{owner_link\}/",
  686.                          "/\{actor_name\}/",
  687.                          "/\{actor_email\}/",
  688.                          "/\{actor_link\}/",
  689.                          "/\{proposal_url\}/",
  690.                          "/\{end_voting_time\}/",
  691.                          "/\{vote_value\}/",
  692.                          "/\{vote_url\}/",
  693.                          "/\{email_pear_dev\}/",
  694.                          "/\{email_pear_group\}/",
  695.                          "/\{comment\}/",
  696.                          "/\{vote_result\}/",
  697.                          "/\{vote_conditional\}/"
  698.                          );
  699.         $replacements = array(
  700.                               $this->pkg_category,
  701.                               $this->pkg_name,
  702.                               (isset($ownerinfo['name'])) $ownerinfo['name'"",
  703.                               (isset($ownerinfo['email'])) "<{$ownerinfo['email']}>" : '',
  704.                               (isset($ownerinfo['handle'])) ? user_link($ownerinfo['handle'], true) : "",
  705.                               (isset($actorinfo['name'])) ? $actorinfo['name'] : "",
  706.                               (isset($actorinfo['email'])) ? $actorinfo['email'] : "",
  707.                               (isset($actorinfo['handle'])) ? "http://" . PEAR_CHANNELNAME . "/user/".$actorinfo['handle'] : "",
  708.                               $proposal_url,
  709.                               format_date($end_voting_time),
  710.                               (isset($vote)) ? $vote->value : 0,
  711.                               (isset($vote)) $vote_url "",
  712.                               PROPOSAL_MAIL_PEAR_DEV,
  713.                               PROPOSAL_MAIL_PEAR_GROUP,
  714.                               (isset($comment)) ? wordwrap($comment'',
  715.                               (isset($vote_result)) $vote_result '',
  716.                               (isset($vote_conditional)) $vote_conditional ""
  717.                               );
  718.  
  719.         $email = preg_replace($replace$replacements$email);
  720.         $email['text'.= PROPOSAL_EMAIL_POSTFIX;
  721.  
  722.         if (is_object($auth_user)) {
  723.             $from = '"' . $auth_user->name . '" <' $auth_user->email . '>';
  724.         } else {
  725.             $from = PROPOSAL_MAIL_FROM ;
  726.         }
  727.  
  728.         $to = explode(", ", $email['to']);
  729.         $email['to'] = array_shift($to);
  730.         $headers = "CC: ". implode(", ", $to) . "\n";
  731.         $headers .= "From: " . $from . "\n";
  732.         $headers .= "X-Mailer: " . "PEPr, PEAR Proposal System" . "\n";
  733.         $headers .= "X-PEAR-Category: " . $this->pkg_category . "\n";
  734.         $headers .= "X-PEAR-Package: " $this->pkg_name . "\n";
  735.         $headers .= "X-PEPr-Status: " $this->getStatus("\n";
  736.  
  737.         if ($event == "change_status_proposal"{
  738.             $headers .= "Message-ID: <proposal-" . $this->id . "@" . PEAR_CHANNELNAME . ">\n";
  739.         } else {
  740.             $headers .= "In-Reply-To: <proposal-" . $this->id . "@" . PEAR_CHANNELNAME . ">\n";
  741.         }
  742.  
  743.         if (!DEVBOX) {
  744.             $res = mail($email['to'], $email['subject'], $email['text'],
  745.                         $headers, '-f ' . PEAR_BOUNCE_EMAIL);
  746.         } else {
  747.             $res = true;
  748.         }
  749.         if (!$res) {
  750.             return PEAR::raiseError('Could not send notification email.');
  751.         }
  752.         return true;
  753.     }

Documentation generated on Mon, 11 Mar 2019 15:44:05 -0400 by phpDocumentor 1.4.4. PEAR Logo Copyright © PHP Group 2004.