/** * Create new bins, with random content from an original bin * * @param User $u * @param Bin $bin * @param array $params * @return array $counts */ public static function randomize($u, $bin, $params) { $stats = self::init_stats($stats = array('total', 'insert', 'duplicate', 'invalid')); $stats['bin_uuids'] = array(); $num = isset($params['num']) ? $params['num'] : 1; $size = isset($params['size']) ? $params['size'] : null; // sanity checking $conn = AIR2_DBManager::get_master_connection(); $q = "select count(*) from bin_source where bsrc_bin_id = ?"; $total = $conn->fetchOne($q, array($bin->bin_id), 0); if ($num < 0 || $num > 20 || $num > $total) { throw new Exception("Invalid num {$num} for randomize!"); } if ($size && ($size < 1 || $size * $num > $total)) { throw new Exception("Invalid size {$size} for randomize (total={$total} num={$num})!"); } // calculate size of each bin $bin_sizes = array_fill(0, $num, $size ? $size : 0); if (!$size) { $sz_idx = 0; for ($i = 0; $i < $total; $i++) { $bin_sizes[$sz_idx]++; $sz_idx = ($sz_idx + 1) % $num; } } // select in random order (mysql does this faster now than previous versions) $q = "select bsrc_src_id from bin_source where bsrc_bin_id = ? order by RAND()"; if ($size) { $q .= " limit " . $num * $size; } $src_ids = $conn->fetchColumn($q, array($bin->bin_id), 0); // create bins, and insert items $curr_offset = 0; foreach ($bin_sizes as $bidx => $bsize) { $b = new Bin(); $b->bin_user_id = $u->user_id; $b->bin_name = "{$bin->bin_name} - Random " . ($bidx + 1); $b->bin_desc = "Random output from bin: '{$bin->bin_name}'"; $b->save(); $stats['bin_uuids'][] = $b->bin_uuid; $add_ids = array_slice($src_ids, $curr_offset, $bsize); $curr_offset += $bsize; $bstats = AIR2Bin::add_sources($b, $add_ids); $stats['insert'] += $bstats['insert']; $stats['total'] += $bstats['total']; } return $stats; }