static function choose($articles) { $consumed = array(); $consumeArticle = function (&$spot, $i) use(&$articles, &$consumed) { $spot = array('title' => @$articles[$i]['title'], 'image' => @$articles[$i]['image'], 'dims' => $spot); $consumed[] = $i; }; $taller = self::findFirstTall($articles); $large = self::findFirstLarge($articles, $consumed); // Get formats based on whether there is an image that could // work as a 1x2 image // Disable Tall formats for now since they are causing problems $possibleFormats = self::getPossibleWideFormats(); $seed = self::stringToNumber($articles[0]['image']->getSha1()); mt_srand($seed); $pos = mt_rand(0, count($possibleFormats) - 1); $format = $possibleFormats[$pos]; // Only consider the first count($articles) - $trim articles // from the stream because we don't want to leave out of order // elements unconsumed. $spots = 0; foreach ($format as $spot) { if ($spot) { $spots++; } } if (count($articles) > $spots) { array_splice($articles, $spots); } // If we have a suitable 1x2 image, use it first -- there is at // most one 1x2 image per format if ($taller >= 0) { foreach ($format as &$spot) { // find the taller image spot if ($spot == '1x2') { $consumeArticle($spot, $taller); break; } } } // If we have a suitable 2x2 image, use that next -- this is at // most one 2x2 image per format if ($large >= 0) { foreach ($format as &$spot) { if (is_string($spot) && $spot == '2x2') { $consumeArticle($spot, $large); break; } } } // Next, sort the images by "flatness" to put the appropriate // images into 2x1 slots. There can be multiple 2x1 slots in a // format. $flatness = self::sortByFlatness($articles, $consumed); foreach ($format as &$spot) { if (count($flatness) == 0) { break; } if (is_string($spot) && $spot == '2x1') { $flat = array_shift($flatness); // Make the default image the wide one if (preg_match("@Default_wikihow_(green|blue)(_intl)?.png@", $articles[$flat]['image']->getPath())) { $articles[$flat]['image'] = Wikitext::getDefaultTitleImage($articles[$flat]['title'], true); } $consumeArticle($spot, $flat); } } // Fill the rest of the spots with the rest of the articles -- // this should only be 1x1 elements now. $i = 0; foreach ($format as &$spot) { // skip already consumed articles while (in_array($i, $consumed)) { $i++; } if (!$spot || !is_string($spot)) { // nothing } elseif ($i < count($articles)) { $consumeArticle($spot, $i); $i++; } else { $spot = array('title' => null, 'image' => null, 'dims' => $spot); } } return array($format, $consumed); }