/** * Add new package * * @param array * @return mixed ID of new package or PEAR error object */ static function add($data) { global $dbh, $auth_user; // name, category // license, summary, description // lead extract($data); if (empty($license)) { $license = 'BSD License'; } if (!empty($category) && (int) $category == 0) { $sql = 'SELECT id FROM categories WHERE name = ?'; $category = $dbh->getOne($sql, array($category)); } if (empty($category)) { return PEAR::raiseError("package::add: invalid `category' field"); } if (empty($name)) { return PEAR::raiseError("package::add: invalid `name' field"); } $query = ' INSERT INTO packages (id, name, package_type, category, license, summary, description, homepage, cvs_link) VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?)'; $id = $dbh->nextId('packages'); $err = $dbh->query($query, array($id, $name, $type, $category, $license, $summary, $description, $homepage, $cvs_link)); if (DB::isError($err)) { return $err; } $sql = 'UPDATE categories SET npackages = npackages + 1 WHERE id = ?'; $err = $dbh->query($sql, array($category)); if (DB::isError($err)) { return $err; } include_once 'pear-database-maintainer.php'; $err = maintainer::add($id, $lead, 'lead'); if (isset($lead) && DB::isError($err)) { return $err; } $event = $auth_user->handle . " (" . $auth_user->name . ") has added a new package " . $name; $mailtext = $event . "\n\nApprove: http://" . PEAR_CHANNELNAME . "/admin/package-approval.php?approve=" . $id; $mailtext .= "\nReject: http://" . PEAR_CHANNELNAME . "/admin/package-approval.php?reject=" . $id; // {{{ Logging mechanism require_once "Damblan/Log.php"; require_once "Damblan/Log/Mail.php"; // Syslog $logger = new Damblan_Log(); $logger->log($event); // Logging via email $logger = new Damblan_Log_Mail(); $logger->setRecipients("*****@*****.**"); $logger->setHeader("From", $auth_user->email); $logger->setHeader("Message-Id", "<approve-request-" . $id . "@" . PEAR_CHANNELNAME . ">"); $logger->setHeader("Subject", "New package"); $logger->log($mailtext); // }}} return $id; }
$name = $pkg['name']; $type = $pkg['type']; $summary = stripslashes($pkg['summary']); $license = $pkg['license']; $description = stripslashes($pkg['description']); $category = $pkg['category']; $homepage = $pkg['homepage']; $pacid = $pkg['packageid']; $cvs_link = $pkg['cvs_link']; $doc_link = $pkg['doc_link']; $bug_link = $pkg['bug_link']; $unmaintained = $pkg['unmaintained'] ? 'Y' : 'N'; $supersede = (bool) $pkg['new_channel']; // Maintainer information include_once 'pear-database-maintainer.php'; $maintainers = maintainer::get($pacid); $accounts = '<ul>' . "\n"; //$bugs = new PEAR_Bugs; foreach ($maintainers as $handle => $row) { //$buginfo = $bugs->getRank($handle); $accounts .= '<li>'; $accounts .= user_link($handle); $accounts .= ' (' . $row['role'] . ($row['active'] == 0 ? ', inactive' : ''); $accounts .= ')</li>' . "\n"; } $accounts .= '</ul>' . "\n"; $channel_name = PEAR_CHANNELNAME; if ($pkg['blocktrackbacks']) { $trackback_header = ''; } else { $trackback_uri = "http://{$channel_name}/trackback/trackback.php?id={$name}";
/** * Update user and roles of a package * * @static * @param int $pkgid The package id to update * @param array $users Assoc array containing the list of users * in the form: '<user>' => array('role' => '<role>', 'active' => '<active>') * @return mixed PEAR_Error or true */ function updateAll($pkgid, $users) { global $dbh, $auth_user; $admin = $auth_user->isAdmin(); // Only admins and leads can do this. if (maintainer::mayUpdate($pkgid) == false) { return PEAR::raiseError('maintainer::updateAll: insufficient privileges'); } $pkg_name = package::info((int) $pkgid, "name", true); // Needed for logging if (empty($pkg_name)) { PEAR::raiseError('maintainer::updateAll: no such package'); } $old = maintainer::get($pkgid); if (DB::isError($old)) { return $old; } $old_users = array_keys($old); $new_users = array_keys($users); if (!$admin && !in_array($auth_user->handle, $new_users)) { return PEAR::raiseError("You can not delete your own maintainer role or you will not " . "be able to complete the update process. Set your name " . "in package.xml or let the new lead developer upload " . "the new release"); } foreach ($users as $user => $u) { $role = $u['role']; $active = $u['active']; if (!maintainer::isValidRole($role)) { return PEAR::raiseError("invalid role '{$role}' for user '{$user}'"); } // The user is not present -> add him if (!in_array($user, $old_users)) { $e = maintainer::add($pkgid, $user, $role, $active); if (PEAR::isError($e)) { return $e; } continue; } // Users exists but role has changed -> update it if ($role != $old[$user]['role']) { $res = maintainer::update($pkgid, $user, $role, $active); if (DB::isError($res)) { return $res; } } } // Drop users who are no longer maintainers foreach ($old_users as $old_user) { if (!in_array($old_user, $new_users)) { $res = maintainer::remove($pkgid, $old_user); if (DB::isError($res)) { return $res; } } } return true; }
if ($_POST['captcha'] != $_SESSION['answer']) { $errors[] = 'Incorrect Captcha'; } } // try to verify the user if (isset($auth_user)) { $_POST['in']['handle'] = $auth_user->handle; } if (!$errors) { /* * Skip did_luser_search check if the user is logged in * and is a pear developer */ if (isset($auth_user) && auth_check('pear.dev')) { require_once 'pear-database-maintainer.php'; $m = maintainer::get($_POST['in']['package_name'], false, true); if (isset($m[$auth_user->handle]) && in_array($m[$auth_user->handle]['role'], array('lead', 'developer'))) { $_POST['in']['did_luser_search'] = 1; } } /* * When user submits a report, do a search and display * the results before allowing them to continue. */ if (!isset($_POST['in']['did_luser_search']) || $_POST['in']['did_luser_search'] == '0') { $_POST['in']['did_luser_search'] = 1; // search for a match using keywords from the subject $sdesc = $_POST['in']['sdesc']; /* * If they are filing a feature request, * only look for similar features
/** * Get maintainers to inform of a trackback (the lead maintainers of a package). * * * @since * @access public * @param boolean $activeOnly To get only active leads * is set to false by default so there's * no bc problems. * * @return array(string) The list of maintainer emails. */ function getMaintainers($activeOnly = true) { include_once 'pear-database-maintainer.php'; $maintainers = maintainer::get($this->get('id'), true, $activeOnly); $res = array(); include_once 'pear-database-user.php'; foreach ($maintainers as $maintainer => $data) { $tmpUser = user::info($maintainer, 'email'); if (empty($tmpUser['email'])) { continue; } $res[] = $tmpUser['email']; } return $res; }
function isAllowed($package) { global $auth_user; auth_require(); $lead = in_array($auth_user->handle, array_keys(maintainer::get($package, true))); $admin = user::isAdmin($auth_user->handle); return $lead || $admin; }
break; } $license = $info->getLicense(); if (is_array($license)) { $license = $license['_content']; } $users = array(); foreach ($info->getMaintainers() as $user) { if (!user::exists($user['handle'])) { $errors[] = 'Unknown user: '******'handle']; continue; } $users[strtolower($user['handle'])] = array('role' => $user['role'], 'active' => !isset($user['active']) || $user['active'] == 'yes'); } include_once 'pear-database-maintainer.php'; $e = maintainer::updateAll($pacid, $users, false, true); if (PEAR::isError($e)) { $errors[] = $e->getMessage(); break; } $e = package::updateInfo($pacid, array('summary' => $info->getSummary(), 'description' => $info->getDescription(), 'license' => $license)); if (PEAR::isError($e)) { $errors[] = $e->getMessage(); break; } include_once 'pear-rest.php'; $pear_rest = new pearweb_Channel_REST_Generator(PEAR_REST_PATH, $dbh); $return = $pear_rest->savePackageMaintainerREST($info->getPackage()); if (PEAR::isError($return)) { if (auth_check('pear.admin')) { $errors[] = $return->getMessage();
/** * Get maintainers * * Get maintainers to inform of a trackback (the * lead maintainers of a package). * * @since * @access public * @param boolean $activeOnly To get only active leads * is set to false by default so there's * no bc problems. * * @return array(string) The list of maintainer emails. */ function getMaintainers($id, $leadOnly = false, $activeOnly = true) { include_once 'pear-database-maintainer.php'; $maintainers = maintainer::get($id, $leadOnly, $activeOnly); $res = array(); include_once 'pear-database-user.php'; foreach ($maintainers as $maintainer => $data) { $tmpUser = user::info($maintainer, 'email'); if (!is_array($tmpUser) || !isset($tmpUser['email'])) { continue; } $res[] = $tmpUser['email']; } return $res; }
if (isset($roles[$handle]) && $info['role'] != $roles[$handle]) { $update = 1; $update_role = $roles[$handle]; } else { $update_role = $info['role']; } if (isset($active[$handle])) { $update_active = 1; $update = 1; } elseif ($info['active'] == 1 && $handle != $new) { $update_active = 0; $update = 1; } // Do not add again the newly added maintainer to the list if ($update == 1 && $handle != $new) { maintainer::update($pid, $handle, $update_role, $update_active); $maintainers[$handle]['role'] = $update_role; $maintainers[$handle]['active'] = $update_active; } $update = 0; } /* // TODO do the SVN push here $query = ' SELECT handle FROM maintains WHERE package = ? AND (role = ? OR role = ?) AND active = 1 ORDER BY active DESC'; $values = array($_POST['name'], 'lead', 'developer'); $maintainers = $dbh->getAll($query, $values, DB_FETCHMODE_ASSOC);
//we have no "created" data in our database. use first release end($pkg['releases']); $p->created = reset(explode(' ', $pkg['releases'][key($pkg['releases'])]['releasedate'])); $p->shortdesc = $pkg['summary']; $p->shortdesc['xml:lang'] = 'en'; $p->description = $pkg['description']; $p->description['xml:lang'] = 'en'; $p->{'mailing-list'}[0]['rdf:resource'] = 'http://pear.php.net/support/lists.php'; $p->{'mailing-list'}[1]['rdf:resource'] = 'http://news.php.net/php.pear.general'; $p->{'mailing-list'}[2]['rdf:resource'] = 'http://news.php.net/php.pear.dev'; $p->{'download-page'}['rdf:resource'] = $url . '/download'; /* * DOAP: helper, tester, translator, documenter, developer, maintainer * PEAR: helper, contributor, developer, lead */ $maintainers = maintainer::getDetailled($pkg['packageid']); //PEAR -> DOAP $rolemap = array('helper' => 'helper', 'contributor' => 'helper', 'developer' => 'developer', 'lead' => 'maintainer'); $rolecounter = array('helper' => 0, 'developer' => 0, 'maintainer' => 0); foreach ($maintainers as $nick => $maint) { $role = $rolemap[$maint['role']]; $n = $rolecounter[$role]; $p->{$role}[$n]->{'foaf:Person'}->{'foaf:nick'} = $nick; $p->{$role}[$n]->{'foaf:Person'}->{'foaf:name'} = $maint['name']; $p->{$role}[$n]->{'foaf:Person'}->{'foaf:homepage'}['rdf:resource'] = $maint['homepage']; $p->{$role}[$n]->{'foaf:Person'}->{'foaf:mbox_sha1sum'} = sha1('mailto:' . $maint['email']); if ($maint['longitude'] != '') { $p->{$role}[$n]->{'foaf:Person'}->{'foaf:based_near'}->{'geo:Point'}['geo:lat'] = $maint['latitude']; $p->{$role}[$n]->{'foaf:Person'}->{'foaf:based_near'}->{'geo:Point'}['geo:long'] = $maint['longitude']; } ++$rolecounter[$role];
// Get the database class. require_once 'DB.php'; $options = array('persistent' => false, 'portability' => DB_PORTABILITY_ALL); $dbh =& DB::connect(PEAR_DATABASE_DSN, $options); if (DB::isError($dbh)) { die("Failed to connect: {$dsn}\n"); } require_once 'pear-database-maintainer.php'; require_once 'pear-database-note.php'; require_once 'Damblan/Karma.php'; $karma = new Damblan_Karma($dbh); $karma_level = 'pecl.dev'; $sql = "SELECT p.name, p.id\n FROM packages p\n WHERE p.package_type = 'pecl'\n ORDER BY p.name"; $packages = $dbh->getAssoc($sql, false, null, DB_FETCHMODE_ASSOC); foreach ($packages as $n => $id) { $m = maintainer::get((int) $id); if (!empty($m)) { echo "\nAltering karma for maintainers of {$n} package id {$id}\n"; foreach ($m as $handle => $m_data) { if (!$karma->has($handle, $karma_level)) { echo "Giving {$handle} {$karma_level} karma\n"; // Bypassing damblan karma because it needs a logged in user $id = $dbh->nextId('karma'); if (DB::isError($id)) { echo "Couldn't get a new id from the karma table\n"; exit; } $query = 'INSERT INTO karma (id, user, level, granted_by, granted_at) VALUES (?, ?, ?, ?, NOW())'; $sth = $dbh->query($query, array($id, $handle, $karma_level, 'peclweb')); if (DB::isError($sth)) {
/** * Update user and roles of a package * * @static * @param int $pkgid The package id to update * @param array $users Assoc array containing the list of users * in the form: '<user>' => array('role' => '<role>', 'active' => '<active>') * @param bool Whether to print the logging information to the screen * @return mixed PEAR_Error or true */ static function updateAll($pkgid, $users, $print = false, $releasing = false) { require_once 'Damblan/Log.php'; global $dbh, $auth_user; // Only admins and leads can do this. if (maintainer::mayUpdate($pkgid) == false) { return PEAR::raiseError('maintainer::updateAll: insufficient privileges'); } $logger = new Damblan_Log(); if ($print) { require_once 'Damblan/Log/Print.php'; $observer = new Damblan_Log_Print(); $logger->attach($observer); } include_once 'pear-database-package.php'; $pkg_name = package::info((int) $pkgid, "name"); // Needed for logging if (empty($pkg_name)) { PEAR::raiseError('maintainer::updateAll: no such package'); } $old = maintainer::get($pkgid); if (DB::isError($old)) { return $old; } $old_users = array_keys($old); $new_users = array_keys($users); $admin = $auth_user->isAdmin(); $qa = $auth_user->isQA(); if (!$admin && !$qa && !in_array($auth_user->handle, $new_users)) { return PEAR::raiseError("You can not delete your own maintainer role or you will not " . "be able to complete the update process. Set your name " . "in package.xml or let the new lead developer upload " . "the new release"); } if ($releasing && user::maintains($auth_user->handle, (int) $pkgid, 'lead') && $users[$auth_user->handle]['role'] != 'lead') { return PEAR::raiseError('You cannot demote your role from lead to ' . $users[$auth_user->handle]['role']); } foreach ($users as $user => $u) { $role = $u['role']; $active = $u['active']; if (!maintainer::isValidRole($role)) { return PEAR::raiseError("invalid role '{$role}' for user '{$user}'"); } // The user is not present -> add him if (!in_array($user, $old_users)) { $e = maintainer::add($pkgid, $user, $role, $active); if (PEAR::isError($e)) { return $e; } $logger->log("[Maintainer] NEW: " . $user . " (" . $role . ") to package " . $pkg_name . " by " . $auth_user->handle); continue; } // Users exists but the role or the "active" flag have changed -> update it if ($role != $old[$user]['role'] || $active != $old[$user]['active']) { $res = maintainer::update($pkgid, $user, $role, $active); if (DB::isError($res)) { return $res; } $logger->log("[Maintainer] UPDATE: " . $user . " (" . $role . ") to package " . $pkg_name . " by " . $auth_user->handle); } } // Drop users who are no longer maintainers foreach ($old_users as $old_user) { if (!in_array($old_user, $new_users)) { $res = maintainer::remove($pkgid, $old_user); if (DB::isError($res)) { return $res; } $logger->log("[Maintainer] REMOVED: " . $old_user . " (" . $role . ") to package " . $pkg_name . " by " . $auth_user->handle); } } return true; }
break; } if (!user::isAdmin($auth_user->handle) && !user::maintains($auth_user->handle, $pacid, 'lead')) { $errors[] = 'You don\'t have permissions to upload this release.'; break; } $e = package::updateInfo($pacid, array('summary' => $info['summary'], 'description' => $info['description'], 'license' => $info['release_license'])); if (PEAR::isError($e)) { $errors[] = $e->getMessage(); break; } $users = array(); foreach ($info['maintainers'] as $user) { $users[strtolower($user['handle'])] = array('role' => $user['role'], 'active' => 1); } $e = maintainer::updateAll($pacid, $users); if (PEAR::isError($e)) { $errors[] = $e->getMessage(); break; } $file = release::upload($info['package'], $info['version'], $info['release_state'], $info['release_notes'], $distfile, md5_file($distfile)); } if (PEAR::isError($file)) { $ui = $file->getUserInfo(); $errors[] = 'Error while uploading package: ' . $file->getMessage() . ($ui ? " ({$ui})" : ''); break; } @unlink($distfile); PEAR::pushErrorHandling(PEAR_ERROR_CALLBACK, 'report_warning'); if (is_a($info, 'PEAR_PackageFile_v1') || is_a($info, 'PEAR_PackageFile_v2')) { release::promote_v2($info, $file);