<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[160] sites/trunk/api.wordpress.org/public_html/core: Open source the credits API.</title>
</head>
<body>
<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; }
#msg dl a { font-weight: bold}
#msg dl a:link { color:#fc3; }
#msg dl a:active { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://meta.trac.wordpress.org/changeset/160">160</a></dd>
<dt>Author</dt> <dd>nacin</dd>
<dt>Date</dt> <dd>2013-12-20 08:36:25 +0000 (Fri, 20 Dec 2013)</dd>
</dl>
<h3>Log Message</h3>
<pre>Open source the credits API. see <a href="http://meta.trac.wordpress.org/ticket/255">#255</a>.</pre>
<h3>Added Paths</h3>
<ul>
<li>sites/trunk/api.wordpress.org/public_html/core/credits/</li>
<li>sites/trunk/api.wordpress.org/public_html/core/credits/1.0/</li>
<li>sites/trunk/api.wordpress.org/public_html/core/credits/1.1/</li>
<li><a href="#sitestrunkapiwordpressorgpublic_htmlcorecredits11indexphp">sites/trunk/api.wordpress.org/public_html/core/credits/1.1/index.php</a></li>
<li><a href="#sitestrunkapiwordpressorgpublic_htmlcorecreditsindexphp">sites/trunk/api.wordpress.org/public_html/core/credits/index.php</a></li>
<li><a href="#sitestrunkapiwordpressorgpublic_htmlcorecreditsshortcodephp">sites/trunk/api.wordpress.org/public_html/core/credits/shortcode.php</a></li>
<li><a href="#sitestrunkapiwordpressorgpublic_htmlcorecreditswp32php">sites/trunk/api.wordpress.org/public_html/core/credits/wp-32.php</a></li>
<li><a href="#sitestrunkapiwordpressorgpublic_htmlcorecreditswpcreditsphp">sites/trunk/api.wordpress.org/public_html/core/credits/wp-credits.php</a></li>
</ul>
</div>
<div id="patch">
<h3>Diff</h3>
<a id="sitestrunkapiwordpressorgpublic_htmlcorecredits11indexphp"></a>
<div class="addfile"><h4>Added: sites/trunk/api.wordpress.org/public_html/core/credits/1.1/index.php (0 => 160)</h4>
<pre class="diff"><span>
<span class="info">--- sites/trunk/api.wordpress.org/public_html/core/credits/1.1/index.php (rev 0)
+++ sites/trunk/api.wordpress.org/public_html/core/credits/1.1/index.php 2013-12-20 08:36:25 UTC (rev 160)
</span><span class="lines">@@ -0,0 +1,5 @@
</span><ins>+<?php
+
+define( 'JSON_RESPONSE', true );
+
+require dirname( __DIR__ ) . '/index.php';
</ins><span class="cx">Property changes on: sites/trunk/api.wordpress.org/public_html/core/credits/1.1/index.php
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<ins>+native
</ins><span class="cx">\ No newline at end of property
</span><a id="sitestrunkapiwordpressorgpublic_htmlcorecreditsindexphp"></a>
<div class="addfile"><h4>Added: sites/trunk/api.wordpress.org/public_html/core/credits/index.php (0 => 160)</h4>
<pre class="diff"><span>
<span class="info">--- sites/trunk/api.wordpress.org/public_html/core/credits/index.php (rev 0)
+++ sites/trunk/api.wordpress.org/public_html/core/credits/index.php 2013-12-20 08:36:25 UTC (rev 160)
</span><span class="lines">@@ -0,0 +1,57 @@
</span><ins>+<?php
+
+$api_root = dirname( dirname( __DIR__ ) );
+
+// Grab some helpers; also WP_CORE_LATEST_RELEASE and WP_CORE_LATEST_BRANCH.
+require "$api_root/init.php";
+// Need HyperDB for DB calls.
+require "$api_root/includes/hyperdb/bb-10-hyper-db.php";
+// Need object cache.
+require "$api_root/includes/object-cache.php";
+
+// The 1.1 endpoint uses JSON. 1.0 uses serialized PHP.
+// Direct access to this file should only occur for CLI usage.
+if ( 'cli' !== php_sapi_name() ) {
+ if ( defined( 'JSON_RESPONSE' ) && JSON_RESPONSE ) {
+ header( 'Content-Type: application/json; charset=UTF-8' );
+ } elseif ( defined( 'JSON_RESPONSE' ) ) {
+ header( 'Content-Type: text/plain; charset=UTF-8' );
+ } else {
+ header( 'HTTP/1.0 400 Bad Request', true, 400 );
+ die( 'Bad request.' );
+ }
+}
+
+// Get WP_Credits library.
+require_once dirname( __FILE__ ) . '/wp-credits.php';
+
+if ( ! function_exists( 'like_escape' ) ) :
+function like_escape( $text ) {
+ return str_replace( array( "%", "_") , array( "\\%", "\\_" ), $text );
+}
+endif;
+
+if ( ! empty( $_GET['version'] ) ) {
+ $version = preg_replace( '/^([.0-9]+).*/', '$1', $_GET['version'] );
+} elseif ( 'cli' == php_sapi_name() && isset( $argv[1] ) ) {
+ $version = preg_replace( '/^([.0-9]+).*/', '$1', $argv[1] );
+} else {
+ $version = WP_CORE_LATEST_RELEASE;
+}
+
+$locale = false;
+// Convert a locale from a WP locale to a GP locale.
+if ( ( isset( $_GET['locale'] ) && 'en_US' != $_GET['locale'] ) || ( 'cli' == php_sapi_name() && isset( $argv[2] ) ) ) {
+ require WPORGPATH . 'translate/glotpress/locales/locales.php';
+ $gp_locale = GP_Locales::by_field( 'wp_locale', isset( $argv[2] ) ? $argv[2] : $_GET['locale'] );
+ if ( $gp_locale ) {
+ $locale = $gp_locale;
+ }
+}
+
+$credits = WP_Credits::factory( $version, $locale );
+$credits->execute();
+
+if ( 'cli' == php_sapi_name() )
+ echo "\n";
+
</ins><span class="cx">Property changes on: sites/trunk/api.wordpress.org/public_html/core/credits/index.php
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<ins>+native
</ins><span class="cx">\ No newline at end of property
</span><a id="sitestrunkapiwordpressorgpublic_htmlcorecreditsshortcodephp"></a>
<div class="addfile"><h4>Added: sites/trunk/api.wordpress.org/public_html/core/credits/shortcode.php (0 => 160)</h4>
<pre class="diff"><span>
<span class="info">--- sites/trunk/api.wordpress.org/public_html/core/credits/shortcode.php (rev 0)
+++ sites/trunk/api.wordpress.org/public_html/core/credits/shortcode.php 2013-12-20 08:36:25 UTC (rev 160)
</span><span class="lines">@@ -0,0 +1,32 @@
</span><ins>+<?php
+
+defined( 'WPINC' ) or exit;
+
+add_shortcode( 'wpcredits', 'wporg_wordpress_credits_shortcode' );
+
+function wporg_wordpress_credits_shortcode( $attrs, $content = null ) {
+ if ( ! isset( $attrs[0] ) ) {
+ return '';
+ }
+
+ require_once __DIR__ . '/wp-credits.php';
+
+ $version = preg_replace( '/^([.0-9]+).*/', '$1', $attrs[0] );
+ $class = WP_Credits::factory( $version, false );
+ $results = $class->get_results();
+
+ $props = $results['groups']['props']['data'];
+ unset( $results['groups']['libraries'], $results['groups']['props'] );
+
+ foreach ( $results['groups'] as $section ) {
+ foreach ( $section['data'] as $person ) {
+ $props[ strtolower( $person[2] ) ] = $person[0];
+ }
+ }
+ asort( $props, SORT_FLAG_CASE | SORT_STRING );
+ $output = array();
+ foreach ( $props as $username => $name ) {
+ $output[] = '<a href="' . sprintf( $results['data']['profiles'], $username ) . '">' . $name . '</a>';
+ }
+ return wp_sprintf( '%l.', $output );
+}
</ins><span class="cx">Property changes on: sites/trunk/api.wordpress.org/public_html/core/credits/shortcode.php
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<ins>+native
</ins><span class="cx">\ No newline at end of property
</span><a id="sitestrunkapiwordpressorgpublic_htmlcorecreditswp32php"></a>
<div class="addfile"><h4>Added: sites/trunk/api.wordpress.org/public_html/core/credits/wp-32.php (0 => 160)</h4>
<pre class="diff"><span>
<span class="info">--- sites/trunk/api.wordpress.org/public_html/core/credits/wp-32.php (rev 0)
+++ sites/trunk/api.wordpress.org/public_html/core/credits/wp-32.php 2013-12-20 08:36:25 UTC (rev 160)
</span><span class="lines">@@ -0,0 +1,202 @@
</span><ins>+<?php
+
+class WP_32_Credits extends WP_Credits {
+
+ function groups() {
+ return array(
+ 'project-leaders' => array(
+ 'name' => 'Project Leaders',
+ 'type' => 'titles',
+ 'shuffle' => true,
+ 'data' => array(
+ 'ryan' => array( 'Ryan Boren', 'Lead Developer' ),
+ 'markjaquith' => array( 'Mark Jaquith', 'Lead Developer', '097a87a525e317519b5ee124820012fb' ),
+ 'matt' => array( 'Matt Mullenweg', 'Cofounder, Project Lead' ),
+ 'azaozz' => array( 'Andrew Ozz', 'Lead Developer' ),
+ 'jenmylo' => array( 'Jen Mylo', 'User Experience Lead' ),
+ 'westi' => array( 'Peter Westwood', 'Lead Developer' ),
+ ),
+ ),
+ 'extended-core-team' => array(
+ 'name' => 'Extended Core Team',
+ 'type' => 'titles',
+ 'shuffle' => true,
+ 'data' => array(
+ 'nacin' => array( 'Andrew Nacin', 'Core Committer' ),
+ 'koop' => array( 'Daryl Koopersmith', 'Guest Committer' ),
+ 'dd32' => array( 'Dion Hulse', 'Core Committer' ),
+ 'josephscott' => array( 'Joseph Scott', 'XML-RPC' ),
+ 'iammattthomas' => array( 'Matt Thomas', 'Designer' ),
+ 'nbachiyski' => array( 'Nikolay Bachiyski', 'Internationalization' ),
+ ),
+ ),
+ 'recent-rockstars' => array(
+ 'name' => 'Recent Rockstars',
+ 'type' => 'titles',
+ 'shuffle' => true,
+ 'data' => array(
+ 'duck_' => array( 'Jon Cave', 'Developer' ),
+ 'scribu' => array( 'Cristi Burcă', 'Developer' ),
+ 'ocean90' => array( 'Dominik Schilling', 'Developer' ),
+ 'iandstewart' => array( 'Ian Stewart', 'Twenty Eleven' ),
+ 'lancewillett' => array( 'Lance Willett', 'Twenty Eleven' ),
+ 'matveb' => array( 'Matías Ventura', 'Twenty Eleven' ),
+ 'aaroncampbell' => array( 'Aaron Campbell', 'Developer' ),
+ 'EmpireOfLight' => array( 'Ben Dunkle', 'Icon Design' ),
+ 'xknown' => array( 'Alex Concha', 'Developer' ),
+ ),
+ ),
+ );
+ }
+
+ function props() {
+ return array(
+ 'aaroncampbell',
+ 'aldenta',
+ 'ampt',
+ 'andrewryno',
+ 'andy',
+ 'batmoo',
+ 'benbalter',
+ 'BenChapman',
+ 'bi0xid',
+ 'blepoxp',
+ 'bluntelk',
+ 'boonebgorges',
+ 'brandonburke',
+ 'Caspie',
+ 'cfinke',
+ 'CharlesClarkson',
+ 'chexee',
+ 'cnorris23',
+ 'coffee2code',
+ 'cyberhobo',
+ 'daniloercoli',
+ 'dcowgill',
+ 'demetris',
+ 'devinreams',
+ 'DH-Shredder',
+ 'dimadin',
+ 'dllh',
+ 'dougwrites',
+ 'dvwallin',
+ 'ericmann',
+ 'fabifott',
+ 'filosofo',
+ 'frumph',
+ 'garyc40',
+ 'greenshady',
+ 'greuben',
+ 'guyn',
+ 'hakre',
+ 'hebbet',
+ 'helen',
+ 'hew',
+ 'holizz',
+ 'jacobwg',
+ 'Jayjdk',
+ 'JDTrower',
+ 'jfarthing84',
+ 'jkudish',
+ 'joelhardi',
+ 'johnbillion',
+ 'johnjamesjacoby',
+ 'johnonolan',
+ 'joostdevalk',
+ 'jorbin',
+ 'jtsternberg',
+ 'kawauso',
+ 'kevinB',
+ 'knutsp',
+ 'koke',
+ 'kovshenin',
+ 'ldebrouwer',
+ 'linuxologos',
+ 'lloydbudd',
+ 'marcis20',
+ 'markmcwilliams',
+ 'MattyRob',
+ 'mcepl',
+ 'mdawaffe',
+ 'mfields',
+ 'MichaelH',
+ 'michaeltyson',
+ 'mintindeed',
+ 'miqrogroove',
+ 'mitchoyoshitaka',
+ 'mrroundhill',
+ 'natecook',
+ 'nathanrice',
+ 'niallkennedy',
+ 'nickbohle',
+ 'nprasath002',
+ 'nuxwin',
+ 'Otto42',
+ 'pavelevap',
+ 'peaceablewhale',
+ 'PeteMall',
+ 'pross',
+ 'ptahdunbar',
+ 'Rahe',
+ 'ramiy',
+ 'rasheed',
+ 'rosshanney',
+ 'ryanimel',
+ 'saracannon',
+ 'SidHarrell',
+ 'sbressler',
+ 'SergeyBiryukov',
+ 'shakenstirred',
+ 'sivel',
+ 'solarissmoke',
+ 'sorich87',
+ 'szadok',
+ 'technosailor',
+ 'tenpura',
+ 'tetele',
+ 'tfnab',
+ 'tigertech',
+ 'trepmal',
+ 'Utkarsh',
+ 'vanillalounge',
+ 'valentinas',
+ 'webduo',
+ 'wpmuguru',
+ 'xibe',
+ 'xknown',
+ 'yoavf',
+ 'zeo',
+ 'ziofix',
+ );
+ }
+
+ function external_libraries() {
+ return array(
+ array( 'Class POP3', 'http://squirrelmail.org/' ),
+ array( 'Color Animations', 'http://plugins.jquery.com/project/color' ),
+ // array( 'ColorPicker', 'http://' ),
+ array( 'Horde Text Diff', 'http://pear.horde.org/' ),
+ array( 'hoverIntent', 'http://plugins.jquery.com/project/hoverIntent' ),
+ array( 'imgAreaSelect', 'http://odyniec.net/projects/imgareaselect/' ),
+ array( 'jQuery', 'http://jquery.com/' ),
+ array( 'jQuery UI', 'http://jqueryui.com/' ),
+ array( 'jQuery Hotkeys', 'https://github.com/tzuryby/jquery.hotkeys' ),
+ array( 'jQuery serializeObject', 'http://benalman.com/projects/jquery-misc-plugins/' ),
+ array( 'jQuery.query', 'http://plugins.jquery.com/project/query-object' ),
+ // array( 'jquery.schedule', 'http://' ),
+ array( 'jQuery.suggest', 'http://plugins.jquery.com/project/suggest' ),
+ array( 'json2', 'https://github.com/douglascrockford/JSON-js' ),
+ array( 'PclZip', 'http://www.phpconcept.net/pclzip/' ),
+ array( 'PemFTP', 'http://www.phpclasses.org/browse/package/1743.html' ),
+ array( 'phpass', 'http://www.openwall.com/phpass/' ),
+ array( 'PHPMailer', 'http://code.google.com/a/apache-extras.org/p/phpmailer/' ),
+ array( 'SimplePie', 'http://simplepie.org/' ),
+ array( 'SWFObject', 'http://code.google.com/p/swfobject/' ),
+ array( 'SWFUpload', 'http://www.swfupload.org/' ),
+ array( 'The Incutio XML-RPC Library', 'http://scripts.incutio.com/xmlrpc/' ),
+ array( 'Thickbox', 'http://jquery.com/demo/thickbox/' ),
+ array( 'TinyMCE', 'http://www.tinymce.com/' ),
+ );
+ }
+
+}
</ins><span class="cx">Property changes on: sites/trunk/api.wordpress.org/public_html/core/credits/wp-32.php
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<ins>+native
</ins><span class="cx">\ No newline at end of property
</span><a id="sitestrunkapiwordpressorgpublic_htmlcorecreditswpcreditsphp"></a>
<div class="addfile"><h4>Added: sites/trunk/api.wordpress.org/public_html/core/credits/wp-credits.php (0 => 160)</h4>
<pre class="diff"><span>
<span class="info">--- sites/trunk/api.wordpress.org/public_html/core/credits/wp-credits.php (rev 0)
+++ sites/trunk/api.wordpress.org/public_html/core/credits/wp-credits.php 2013-12-20 08:36:25 UTC (rev 160)
</span><span class="lines">@@ -0,0 +1,381 @@
</span><ins>+<?php
+
+abstract class WP_Credits {
+
+ abstract protected function groups();
+
+ abstract protected function props();
+
+ abstract protected function external_libraries();
+
+ public static $use_cache = true;
+ public static $set_cache = true;
+ const cache_group = 'core-credits-api';
+ const cache_life = 43200; // 12 hours
+
+ protected $version;
+
+ protected $branch;
+
+ private $groups;
+
+ private $names_in_groups = array();
+
+ private static $cycle_dates = array(
+ '3.2' => '2011-02-23 00:00:00',
+ '3.3' => '2011-07-05 00:00:00',
+ '3.4' => '2011-12-10 00:00:00',
+ '3.5' => '2012-07-01 00:00:00',
+ '3.6' => '2012-12-15 00:00:00',
+ '3.7' => '2013-07-28 00:00:00',
+ '3.8' => '2013-11-01 00:00:00',
+ );
+
+ final public static function factory( $version, $gp_locale ) {
+ $branch = intval( str_replace( '.', '', self::calculate_branch( $version ) ) );
+ $file = dirname( __FILE__ ) . '/wp-' . $branch . '.php';
+ if ( file_exists( $file ) ) {
+ require_once $file;
+ $class = 'WP_' . $branch . '_Credits';
+ $credits = new $class( $version, $gp_locale );
+ return $credits;
+ } elseif ( version_compare( $branch, WP_CORE_STABLE_BRANCH, '>' ) ) {
+ // Grab latest cycle listed.
+ $cycles = self::$cycle_dates;
+ end( $cycles );
+ $branch = str_replace( '.', '', key( $cycles ) );
+ $file = dirname( __FILE__ ) . '/wp-' . $branch . '.php';
+ if ( file_exists( $file ) ) {
+ require_once $file;
+ $class = 'WP_' . $branch . '_Credits';
+ $credits = new $class( $version, $gp_locale );
+ return $credits;
+ }
+ }
+ die();
+ }
+
+ private function __construct( $version, $gp_locale ) {
+ wp_cache_init();
+ $this->version = $version;
+ $this->branch = self::calculate_branch( $this->version );
+ if ( $gp_locale )
+ $this->set_locale_data( $gp_locale );
+ }
+
+ private function cache_set( $key, $value ) {
+ if ( self::$set_cache ) {
+ return wp_cache_set( $key, $value, self::cache_group, self::cache_life );
+ }
+ return false;
+ }
+
+ private function cache_get( $key ) {
+ if ( self::$use_cache ) {
+ return wp_cache_get( $key, self::cache_group );
+ }
+ return false;
+ }
+
+ private static function calculate_branch( $version ) {
+ preg_match( '#^(\d+)\.(\d+)#', $version, $match );
+ return $match[1] . '.' . $match[2];
+ }
+
+ private function set_locale_data( $gp_locale ) {
+ if ( version_compare( WP_CORE_STABLE_BRANCH, $this->branch, '<' ) )
+ $path = 'dev';
+ else
+ $path = $this->branch . '.x';
+
+ // Override the code above. Currently, all history is retained in wp/dev. The branches are w/o history.
+ $path = 'dev';
+
+ $cache_key = array(
+ 'translators' => 'translators-' . $gp_locale->slug . '-' . $this->version . '-' . $path,
+ 'validators' => 'validators-' . $gp_locale->slug . '-' . $this->version,
+ );
+
+ $translators = $this->cache_get( $cache_key['translators'] );
+ $validators = $this->cache_get( $cache_key['validators'] );
+
+ if ( false === $translators ) {
+ $translators = $this->_grab_translators( $gp_locale, $path );
+ $this->cache_set( $cache_key['translators'], $translators );
+ }
+
+ if ( false === $validators ) {
+ $validators = $this->_grab_validators( $gp_locale );
+ $this->cache_set( $cache_key['validators'], $validators );
+ }
+
+ $translators = array_diff_key( $translators, $validators );
+
+ natcasesort( $validators );
+ natcasesort( $translators );
+
+ $this->validators = $validators;
+ $this->translators = $translators;
+ }
+
+ private function _grab_translators( $gp_locale, $path ) {
+ global $wpdb;
+ $path = 'wp/' . $path;
+
+ $locale = $gp_locale->slug;
+
+ $path = $wpdb->escape( like_escape( $path ) . '%' );
+ $locale = $wpdb->escape( $locale );
+
+ $date = $wpdb->prepare( "AND tt.date_added > %s", $this->get_start_date() );
+ if ( $end_date = $this->get_end_date() )
+ $date .= $wpdb->prepare( " AND tt.date_added <= %s", $end_date );
+
+ $users = $wpdb->get_col( "SELECT DISTINCT tt.user_id
+ FROM translate_translations tt
+ INNER JOIN translate_translation_sets tts
+ ON tt.translation_set_id = tts.id
+ INNER JOIN translate_projects tp
+ ON tp.id = tts.project_id
+ WHERE tp.path LIKE '$path'
+ AND tts.locale = '$locale'
+ AND tts.slug = 'default'
+ AND ( tt.status = 'current' || tt.status = 'old' )
+ AND tt.user_id IS NOT NULL
+ $date" );
+
+ if ( ! $users )
+ return array();
+
+ $translator_data = $wpdb->get_results( "SELECT user_nicename, display_name FROM $wpdb->users WHERE ID IN (" . implode( ',', $users ) . ")" );
+
+ $translators = array();
+
+ foreach ( $translator_data as $user ) {
+ if ( $user_nicename == 'nacin' )
+ continue;
+ if ( $user->display_name && $user->display_name != $user->user_nicename && false === strpos( $user->display_name , '?') )
+ $translators[ $user->user_nicename ] = utf8_encode( remove_accents( $user->display_name ) );
+ else
+ $translators[ $user->user_nicename ] = $user->user_nicename;
+ }
+
+ return $translators;
+ }
+
+ private function _grab_validators( $gp_locale ) {
+ global $wpdb;
+ $users = $this->grab_validators( $gp_locale );
+
+ if ( ! $users )
+ return array();
+
+ $validator_data = $wpdb->get_results( "SELECT user_nicename, display_name, user_email FROM $wpdb->users WHERE ID IN (" . implode( ',', $users ) . ")" );
+
+ $validators = array();
+
+ foreach ( $validator_data as $user ) {
+ if ( $user->user_nicename == 'nacin' ) // I stopped taking Spanish in 11th grade, don't show me as a validator when I'm testing things.
+ continue;
+ if ( $user->display_name && $user->display_name != $user->user_nicename && false === strpos( $user->display_name , '?') )
+ $validators[ $user->user_nicename ] = array( utf8_encode( remove_accents( $user->display_name ) ), md5( $user->user_email ), $user->user_nicename );
+ else
+ $validators[ $user->user_nicename ] = array( $user->user_nicename, md5( $user->user_email ), $user->user_nicename );
+ }
+
+ return $validators;
+ }
+
+ protected function grab_validators( $gp_locale ) {
+ global $wpdb;
+ $blog_id = $wpdb->get_var( $wpdb->prepare( "SELECT blog_id FROM ros_blogs INNER JOIN locales ON ros_blogs.domain = CONCAT(locales.subdomain, '.wordpress.org') WHERE locales.locale = %s", $gp_locale->wp_locale ) );
+ if ( $blog_id ) {
+ $meta_key = 'ros_' . intval( $blog_id ) . '_capabilities';
+ return $wpdb->get_col( "SELECT user_id FROM $wpdb->usermeta WHERE meta_key = '$meta_key' AND meta_value NOT LIKE '%subscriber%'" );
+ }
+ return array();
+ }
+
+ final protected function get_start_date() {
+ if ( isset( self::$cycle_dates[ $this->branch ] ) )
+ return self::$cycle_dates[ $this->branch ];
+ }
+
+ final protected function get_end_date() {
+ $next = false;
+ foreach ( self::$cycle_dates as $branch => $date ) {
+ if ( $next )
+ return $date;
+ if ( self::$cycle_dates[ $this->branch ] == $date )
+ $next = true;
+ }
+ return false;
+ }
+
+ private function _data() {
+ return array(
+ 'profiles' => 'http://profiles.wordpress.org/%s',
+ 'version' => $this->branch,
+ );
+ }
+
+ private function _groups() {
+ global $wpdb;
+
+ if ( isset( $this->groups ) )
+ return $this->groups;
+
+ $groups = $this->groups();
+ $fetch_emails_from_user_cache = $fetch_emails_from_db = array();
+
+ foreach ( $groups as $group_slug => $group_data ) {
+ if ( 'list' == $group_data['type'] )
+ continue;
+ foreach ( $group_data['data'] as $k => $person ) {
+ $person = (array) $person;
+ $new_data = array( 'name' => $person[0], 'hash' => '', 'username' => $k, 'title' => '' );
+ $this->names_in_groups[] = $k;
+
+ if ( ! empty( $person[2] ) ) {
+ // array( 'Andrew Nacin', 'Lead Developer', 'md5 hash' )
+ $new_data['title'] = $person[1];
+ $new_data['hash'] = $person[2];
+ } elseif ( empty( $person[1] ) ) {
+ // array( 'Andrew Nacin' )
+ $fetch_emails_from_user_cache[ $k ] = $group_slug;
+ } elseif ( strlen( $person[1] ) === 32 && preg_match('/^[a-f0-9]{32}$/', $person[1] ) ) {
+ // array( 'Andrew Nacin', 'md5 hash' )
+ $new_data['hash'] = $person[1];
+ } else {
+ // array( 'Andrew Nacin', 'Lead Developer' )
+ $new_data['title'] = $person[1];
+ $fetch_emails_from_user_cache[ $k ] = $group_slug;
+ }
+
+ // Temporary:
+ if ( strlen( $new_data['hash'] ) != 32 || strpos( $new_data['hash'], '@' ) ) {
+ $new_data['hash'] = md5( $new_data['hash'] );
+ }
+
+ $group_data['data'][ $k ] = array_values( $new_data );
+ }
+
+ $groups[ $group_slug ]['data'] = $group_data['data'];
+ }
+
+ if ( $fetch_emails_from_user_cache ) {
+ foreach ( $fetch_emails_from_user_cache as $username => $group ) {
+ $user_id = wp_cache_get( $username, 'userlogins' );
+ if ( $user_id ) {
+ if ( $user_object = wp_cache_get( $user_id, 'users' ) ) {
+ $groups[ $group ]['data'][ $username ][1] = md5( strtolower( $user_object->user_email ) );
+ } else {
+ $fetch_emails_from_db[ $username ] = $group;
+ }
+ } else {
+ $fetch_emails_from_db[ $username ] = $group;
+ }
+ }
+ if ( $fetch_emails_from_db ) {
+ $fetched = $wpdb->get_results( "SELECT user_login, ID, user_email FROM $wpdb->users WHERE user_login IN ('" . implode( "', '", array_keys( $fetch_emails_from_db ) ) . "')", OBJECT_K );
+ foreach ( $fetched as $username => $row ) {
+ $groups[ $fetch_emails_from_db[ $username ] ]['data'][ $username ][1] = md5( strtolower( $row->user_email ) );
+ wp_cache_add( $username, $row->ID, 'userlogins' );
+ }
+ }
+ }
+
+ $this->groups = $groups;
+ return $groups;
+ }
+
+ private function _props() {
+ global $wpdb;
+ $props = $this->cache_get( 'props-' . $this->version );
+ if ( $props !== false )
+ return $props;
+
+ $this->_groups(); // Cache groups now.
+
+ $users = $this->props();
+ $users = array_diff( $users, $this->names_in_groups );
+
+ $user_data = $wpdb->get_results( "SELECT user_nicename, display_name FROM $wpdb->users WHERE user_nicename IN ('" . implode( "', '", $users ) . "')" );
+
+ $props = array();
+
+ foreach ( $user_data as $user ) {
+ if ( $user->display_name && $user->display_name != $user->user_nicename && false === strpos( $user->display_name , '?') )
+ $props[ $user->user_nicename ] = utf8_encode( remove_accents( $user->display_name ) );
+ else
+ $props[ $user->user_nicename ] = $user->user_nicename;
+ }
+
+ natcasesort( $props );
+
+ $this->cache_set( 'props-' . $this->version, $props );
+
+ return $props;
+ }
+
+ private function _external_libraries() {
+ return $this->external_libraries();
+ }
+
+ private function _translators() {
+ return $this->translators;
+ }
+
+ private function _validators() {
+ return $this->validators;
+ }
+
+ final public function get_results() {
+ $groups = $this->_groups();
+
+ $groups['props'] = array(
+ 'name' => 'Core Contributors to WordPress %s',
+ 'placeholders' => array( $this->branch ),
+ 'type' => 'list',
+ 'data' => $this->_props(),
+ );
+
+ if ( $this->validators || $this->translators ) {
+ $groups['validators'] = array(
+ 'name' => 'Translators',
+ 'type' => 'compact',
+ 'shuffle' => true,
+ 'data' => $this->_validators(),
+ );
+
+ $groups['translators'] = array(
+ 'name' => false,
+ 'type' => 'list',
+ 'data' => $this->_translators(),
+ );
+ }
+
+ $groups['libraries'] = array(
+ 'name' => 'External Libraries',
+ 'type' => 'libraries',
+ 'data' => $this->_external_libraries(),
+ );
+
+ $data = $this->_data();
+
+ return compact( 'groups', 'data' );
+ }
+
+ final public function execute() {
+ $results = $this->get_results();
+
+ if ( 'cli' === php_sapi_name() ) {
+ print_r( $results );
+ } elseif ( defined( 'JSON_RESPONSE' ) && JSON_RESPONSE ) {
+ echo json_encode( $results );
+ } else {
+ echo serialize( $results );
+ }
+ }
+
+}
</ins><span class="cx">Property changes on: sites/trunk/api.wordpress.org/public_html/core/credits/wp-credits.php
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<ins>+native
</ins><span class="cx">\ No newline at end of property
</span></div>
</body>
</html>