+/**
+ * Returns true if this thumbnail is one that MediaWiki generates
+ * links to on file description pages and possibly parser output.
+ *
+ * $params is considered non-standard if they involve a non-standard
+ * width or any parameter aside from width and page number. The number
+ * of possible files with standard parameters is far less than that of all
+ * possible combinations; rate-limiting for them can thus be more generious.
+ *
+ * @param File $img
+ * @param array $params
+ * @return bool
+ */
+function wfThumbIsStandard( File $img, array $params ) {
+ global $wgThumbLimits, $wgImageLimits;
+ // @TODO: use polymorphism with media handler here
+ if ( array_diff( array_keys( $params ), array( 'width', 'page' ) ) ) {
+ return false; // extra parameters present
+ }
+ if ( isset( $params['width'] ) ) {
+ $widths = $wgThumbLimits;
+ foreach ( $wgImageLimits as $pair ) {
+ $widths[] = $pair[0];
+ }
+ if ( !in_array( $params['width'], $widths ) ) {
+ return false;
+ }
+ }
+ return true;
+}
+
+/**
+ * @param File $img
+ * @param string $thumbName
+ * @param int $limit
+ * @return int|bool
+ */
+function wfThumbIsAttemptThrottled( File $img, $thumbName, $limit ) {
+ global $wgMemc;
+
+ return ( $wgMemc->get( wfThumbAttemptKey( $img, $thumbName ) ) >= $limit );
+}
+
+/**
+ * @param File $img
+ * @param string $thumbName
+ */
+function wfThumbIncrAttemptFailures( File $img, $thumbName ) {
+ global $wgMemc;
+
+ $key = wfThumbAttemptKey( $img, $thumbName );
+ if ( !$wgMemc->incr( $key, 1 ) ) {
+ if ( !$wgMemc->add( $key, 1, 3600 ) ) {
+ $wgMemc->incr( $key, 1 );
+ }
+ }
+}
+
+/**
+ * @param File $img
+ * @param string $thumbName
+ * @return string
+ */
+function wfThumbAttemptKey( File $img, $thumbName ) {
+ global $wgAttemptFailureEpoch;
+
+ return wfMemcKey( 'attempt-failures', $wgAttemptFailureEpoch,
+ $img->getRepo()->getName(), md5( $img->getName() ), md5( $thumbName ) );
+}
+