Status.php 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. <?php
  2. /**
  3. * Generic operation result class
  4. * Has warning/error list, boolean status and arbitrary value
  5. *
  6. * "Good" means the operation was completed with no warnings or errors.
  7. *
  8. * "OK" means the operation was partially or wholly completed.
  9. *
  10. * An operation which is not OK should have errors so that the user can be
  11. * informed as to what went wrong. Calling the fatal() function sets an error
  12. * message and simultaneously switches off the OK flag.
  13. */
  14. class Status {
  15. var $ok = true;
  16. var $value;
  17. /** Counters for batch operations */
  18. var $successCount = 0, $failCount = 0;
  19. /*semi-private*/ var $errors = array();
  20. /*semi-private*/ var $cleanCallback = false;
  21. /**
  22. * Factory function for fatal errors
  23. */
  24. static function newFatal( $message /*, parameters...*/ ) {
  25. $params = func_get_args();
  26. $result = new self;
  27. call_user_func_array( array( &$result, 'error' ), $params );
  28. $result->ok = false;
  29. return $result;
  30. }
  31. static function newGood( $value = null ) {
  32. $result = new self;
  33. $result->value = $value;
  34. return $result;
  35. }
  36. function setResult( $ok, $value = null ) {
  37. $this->ok = $ok;
  38. $this->value = $value;
  39. }
  40. function isGood() {
  41. return $this->ok && !$this->errors;
  42. }
  43. function isOK() {
  44. return $this->ok;
  45. }
  46. function warning( $message /*, parameters... */ ) {
  47. $params = array_slice( func_get_args(), 1 );
  48. $this->errors[] = array(
  49. 'type' => 'warning',
  50. 'message' => $message,
  51. 'params' => $params );
  52. }
  53. /**
  54. * Add an error, do not set fatal flag
  55. * This can be used for non-fatal errors
  56. */
  57. function error( $message /*, parameters... */ ) {
  58. $params = array_slice( func_get_args(), 1 );
  59. $this->errors[] = array(
  60. 'type' => 'error',
  61. 'message' => $message,
  62. 'params' => $params );
  63. }
  64. /**
  65. * Add an error and set OK to false, indicating that the operation as a whole was fatal
  66. */
  67. function fatal( $message /*, parameters... */ ) {
  68. $params = array_slice( func_get_args(), 1 );
  69. $this->errors[] = array(
  70. 'type' => 'error',
  71. 'message' => $message,
  72. 'params' => $params );
  73. $this->ok = false;
  74. }
  75. protected function cleanParams( $params ) {
  76. if ( !$this->cleanCallback ) {
  77. return $params;
  78. }
  79. $cleanParams = array();
  80. foreach ( $params as $i => $param ) {
  81. $cleanParams[$i] = call_user_func( $this->cleanCallback, $param );
  82. }
  83. return $cleanParams;
  84. }
  85. protected function getItemXML( $item ) {
  86. $params = $this->cleanParams( $item['params'] );
  87. $xml = "<{$item['type']}>\n" .
  88. Xml::element( 'message', null, $item['message'] ) . "\n" .
  89. Xml::element( 'text', null, wfMsgReal( $item['message'], $params ) ) ."\n";
  90. foreach ( $params as $param ) {
  91. $xml .= Xml::element( 'param', null, $param );
  92. }
  93. $xml .= "</{$this->type}>\n";
  94. return $xml;
  95. }
  96. /**
  97. * Get the error list as XML
  98. */
  99. function getXML() {
  100. $xml = "<errors>\n";
  101. foreach ( $this->errors as $error ) {
  102. $xml .= $this->getItemXML( $error );
  103. }
  104. $xml .= "</errors>\n";
  105. return $xml;
  106. }
  107. /**
  108. * Get the error list as a wikitext formatted list
  109. * @param string $shortContext A short enclosing context message name, to be used
  110. * when there is a single error
  111. * @param string $longContext A long enclosing context message name, for a list
  112. */
  113. function getWikiText( $shortContext = false, $longContext = false ) {
  114. if ( count( $this->errors ) == 0 ) {
  115. if ( $this->ok ) {
  116. $this->fatal( 'internalerror_info',
  117. __METHOD__." called for a good result, this is incorrect\n" );
  118. } else {
  119. $this->fatal( 'internalerror_info',
  120. __METHOD__.": Invalid result object: no error text but not OK\n" );
  121. }
  122. }
  123. if ( count( $this->errors ) == 1 ) {
  124. $params = array_map( 'wfEscapeWikiText', $this->cleanParams( $this->errors[0]['params'] ) );
  125. $s = wfMsgReal( $this->errors[0]['message'], $params, true, false, false );
  126. if ( $shortContext ) {
  127. $s = wfMsgNoTrans( $shortContext, $s );
  128. } elseif ( $longContext ) {
  129. $s = wfMsgNoTrans( $longContext, "* $s\n" );
  130. }
  131. } else {
  132. $s = '';
  133. foreach ( $this->errors as $error ) {
  134. $params = array_map( 'wfEscapeWikiText', $this->cleanParams( $error['params'] ) );
  135. $s .= '* ' . wfMsgReal( $error['message'], $params, true, false, false ) . "\n";
  136. }
  137. if ( $longContext ) {
  138. $s = wfMsgNoTrans( $longContext, $s );
  139. } elseif ( $shortContext ) {
  140. $s = wfMsgNoTrans( $shortContext, "\n* $s\n" );
  141. }
  142. }
  143. return $s;
  144. }
  145. /**
  146. * Merge another status object into this one
  147. */
  148. function merge( $other, $overwriteValue = false ) {
  149. $this->errors = array_merge( $this->errors, $other->errors );
  150. $this->ok = $this->ok && $other->ok;
  151. if ( $overwriteValue ) {
  152. $this->value = $other->value;
  153. }
  154. $this->successCount += $other->successCount;
  155. $this->failCount += $other->failCount;
  156. }
  157. function getErrorsArray() {
  158. $result = array();
  159. foreach ( $this->errors as $error ) {
  160. if ( $error['type'] == 'error' )
  161. $result[] = $error['message'];
  162. }
  163. return $result;
  164. }
  165. /**
  166. * Returns true if the specified message is present as a warning or error
  167. */
  168. function hasMessage( $msg ) {
  169. foreach ( $this->errors as $error ) {
  170. if ( $error['message'] === $msg ) {
  171. return true;
  172. }
  173. }
  174. return false;
  175. }
  176. }