{"id":17871,"date":"2023-01-05T08:49:11","date_gmt":"2023-01-05T08:49:11","guid":{"rendered":"https:\/\/44.225.35.201\/testrail\/docs\/801\/server-guide\/customizations-and-extensions\/custom-report-plugins\/reports-building-a-custom-report-plugin-3-3\/"},"modified":"2023-01-05T18:06:17","modified_gmt":"2023-01-05T09:06:17","slug":"custom-report-3","status":"publish","type":"page","link":"https:\/\/docs.testrail.techmatrix.jp\/testrail\/docs\/9\/server-guide\/customizations-and-extensions\/custom-report-plugins\/custom-report-3\/","title":{"rendered":"\u30ab\u30b9\u30bf\u30e0 \u30ec\u30dd\u30fc\u30c8 \u30d7\u30e9\u30b0\u30a4\u30f3\u306e\u4f5c\u6210 (3\/3)"},"content":{"rendered":"<p><a href=\"\/custom-report-2#i-3\" target=\"_self\" rel=\"noopener\"><strong>\u30ab\u30b9\u30bf\u30e0 \u30ec\u30dd\u30fc\u30c8 \u30d7\u30e9\u30b0\u30a4\u30f3\u306e\u4f5c\u6210\u306e\u524d\u306e\u30d1\u30fc\u30c8<\/strong><\/a>\u3067\u7d39\u4ecb\u3057\u305f\u30ec\u30dd\u30fc\u30c8 \u30d8\u30eb\u30d1\u30fc\u306b\u52a0\u3048\u3066\u3001\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3078\u306e\u76f4\u63a5\u30a2\u30af\u30bb\u30b9\u3082\u30b5\u30dd\u30fc\u30c8\u3055\u308c\u3066\u3044\u307e\u3059\u3002\u3053\u306e\u6700\u5f8c\u306e\u30d1\u30fc\u30c8\u3067\u306f\u3001\u72ec\u81ea\u306e\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9 \u30e2\u30c7\u30eb\u3092\u4f5c\u6210\u3059\u308b\u3068\u3053\u308d\u304b\u3089\u3001\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3078\u306e\u30a2\u30af\u30bb\u30b9\u3001\u30c7\u30fc\u30bf\u3092\u30d3\u30e5\u30fc\u306b\u6e21\u3057\u3066\u30ec\u30f3\u30c0\u30ea\u30f3\u30b0\u3059\u308b\u307e\u3067\u306e\u3059\u3079\u3066\u306b\u3064\u3044\u3066\u8aac\u660e\u3057\u307e\u3059\u3002<\/p>\n<div class=\"callout callout--info\">\n<p>[et_pb_text admin_label=&#8221;Note&#8221; _builder_version=&#8221;4.4.2&#8243; background_color=&#8221;#F0F8FF&#8221; hover_enabled=&#8221;0&#8243; border_width_all=&#8221;1px&#8221; border_color_all=&#8221;#b0c4de&#8221;]<\/p>\n<p>\u3053\u306e\u30da\u30fc\u30b8\u3067\u8aac\u660e\u3057\u3066\u3044\u308b\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9 \u30a2\u30af\u30bb\u30b9 \u30e1\u30bd\u30c3\u30c9\u3092\u4f7f\u7528\u3057\u3066\u66f8\u304d\u8fbc\u307f\u30af\u30a8\u30ea\u30fc\u3092\u5b9f\u884c\u3057\u3001TestRail \u306e\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3092\u5909\u66f4\u3059\u308b\u3053\u3068\u306f\u3001\u6280\u8853\u7684\u306b\u306f\u53ef\u80fd\u3067\u3059\u304c\u3001\u30b5\u30dd\u30fc\u30c8\u3055\u308c\u3066\u3044\u307e\u305b\u3093\u3002\u8aad\u307f\u53d6\u308a\u30af\u30a8\u30ea\u30fc\u306e\u305f\u3081\u306b\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306b\u30a2\u30af\u30bb\u30b9\u3059\u308b\u3053\u3068\u3060\u3051\u304c\u8a31\u53ef\u3055\u308c\u3066\u3044\u307e\u3059\u3002<\/p>\n<p>[\/et_pb_text]<\/p>\n<h2><span style=\"color: revert; font-size: revert; font-weight: revert;\">\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9 \u30a2\u30af\u30bb\u30b9<\/span><\/h2>\n<\/div>\n<p>\u901a\u5e38\u3001\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9 \u30b3\u30fc\u30c9\u3068\u5b9f\u969b\u306e\u30ec\u30dd\u30fc\u30c8 \u30ed\u30b8\u30c3\u30af\u3092\u5206\u96e2\u3059\u308b\u305f\u3081\u306b\u3001\u30ec\u30dd\u30fc\u30c8 \u30d7\u30e9\u30b0\u30a4\u30f3\u306e\u30ab\u30b9\u30bf\u30e0 \u30c7\u30fc\u30bf\u30d9\u30fc\u30b9 \u30af\u30a8\u30ea\u30fc\u306f\u30e2\u30c7\u30eb\u306b\u30d0\u30f3\u30c9\u30eb\u3055\u308c\u307e\u3059\u3002\u30b5\u30f3\u30d7\u30eb \u30ec\u30dd\u30fc\u30c8 \u30d7\u30e9\u30b0\u30a4\u30f3\u3067\u3082\u3053\u306e\u539f\u5247\u306b\u5f93\u3044\u3001report.php \u306e\u30b3\u30fc\u30c9\u3068\u5fc5\u8981\u306a\u5909\u66f4\u3092\u78ba\u8a8d\u3057\u307e\u3059\u3002<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"php\">class Tests_property_results_report_plugin extends Report_plugin\n{\n  private $_model;\n \n  ..\n \n  public function __construct()\n  {\n    parent::__construct();\n    $this-&gt;_model = new Tests_property_results_summary_model();\n    $this-&gt;_model-&gt;init();\n    $this-&gt;_controls = $this-&gt;create_controls(\n      self::$_control_schema\n    );\n  }\n \n  ..\n}\n \nclass Tests_property_results_summary_model extends BaseModel\n{\n  ..\n}<\/pre>\n<p>\u30e2\u30c7\u30eb\u306f\u3001\u57fa\u672c\u30e2\u30c7\u30eb (BaseModel) \u304b\u3089\u6d3e\u751f\u3059\u308b\u72ec\u7acb\u3057\u305f\u30af\u30e9\u30b9\u3067\u3059\u3002\u3053\u306e\u30af\u30e9\u30b9\u306e\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u306f\u3001\u30ec\u30dd\u30fc\u30c8 \u30d7\u30e9\u30b0\u30a4\u30f3\u306e\u30b3\u30f3\u30b9\u30c8\u30e9\u30af\u30bf\u30fc\u3067\u4f5c\u6210\u3055\u308c\u3001<strong>$this\u2192_helper<\/strong> \u306b\u3088\u3063\u3066\u30a2\u30af\u30bb\u30b9\u3067\u304d\u307e\u3059\u3002\u30e2\u30c7\u30eb\u306b\u6700\u521d\u306e\u30e1\u30bd\u30c3\u30c9\u3092\u8ffd\u52a0\u3059\u308b\u3053\u3068\u304c\u3067\u304d\u307e\u3059\u3002<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"php\">class Tests_property_results_summary_model extends BaseModel\n{\n  public function get_statuses()\n  {\n    $this-&gt;db-&gt;select('*');\n    $this-&gt;db-&gt;from('statuses');\n    $this-&gt;db-&gt;where('is_active', true);\n    $this-&gt;db-&gt;order_by('display_order');\n    return $this-&gt;db-&gt;get_result();\n  }\n \n  public function get_types()\n  {\n    $this-&gt;db-&gt;select('*');\n    $this-&gt;db-&gt;from('case_types');\n    $this-&gt;db-&gt;where('is_deleted', false);\n    $this-&gt;db-&gt;order_by('name', 'asc');\n    return $this-&gt;db-&gt;get_result();\n  }\n \n  public function get_type_results($run_ids, $type_id)\n  {\n    $query = $this-&gt;db-&gt;query(\n      'SELECT\n        tests.status_id,\n        COUNT(*) as status_count\n      FROM\n        tests\n      JOIN\n        cases\n          on\n        cases.id = tests.content_id\n      WHERE\n        tests.run_id in ({0}) and\n        cases.type_id = {1}\n      GROUP BY\n        tests.status_id',\n      $run_ids,\n      $type_id\n    );\n \n    $results = $query-&gt;result();\n    return obj::get_lookup_scalar(\n      $results,\n      'status_id',\n      'status_count'\n    );\n  }\n \n  \/* Skipped for priorities *\/\n \n  ..\n}<\/pre>\n<p>\u3053\u3053\u3067\u8aac\u660e\u3059\u308b\u3079\u304d\u30dd\u30a4\u30f3\u30c8\u304c\u3044\u304f\u3064\u304b\u3042\u308a\u307e\u3059\u3002\u30e2\u30c7\u30eb\u306f <strong>$this\u2192_db<\/strong> \u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u3092\u4ecb\u3057\u3066\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306b\u30a2\u30af\u30bb\u30b9\u3057\u3001(<strong>get_type_results<\/strong> \u306e\u3088\u3046\u306b) \u76f4\u63a5\u30af\u30a8\u30ea\u30fc\u3092\u767a\u884c\u3059\u308b\u304b\u3001(<strong>get_statuses<\/strong> \u306e\u3088\u3046\u306b) \u8efd\u91cf\u306e\u30e9\u30c3\u30d1\u30fc\u3092\u4f7f\u7528\u3057\u307e\u3059\u3002\u30e9\u30c3\u30d1\u30fc\u306f\u3059\u3079\u3066\u306e SQL \u30b3\u30de\u30f3\u30c9\u3092\u30b5\u30dd\u30fc\u30c8\u3057\u3066\u3044\u308b\u308f\u3051\u3067\u306f\u306a\u3044\u306e\u3067\u3001\u5358\u7d14\u306a select\u3001from\u3001where\u3001get sequence \u4ee5\u5916\u306e\u8907\u96d1\u306a\u30af\u30a8\u30ea\u30fc\u306b\u306f\u76f4\u63a5\u30af\u30a8\u30ea\u30fc\u3092\u4f7f\u7528\u3059\u308b\u3053\u3068\u3092\u304a\u52e7\u3081\u3057\u307e\u3059\u3002\u3069\u3061\u3089\u306e\u5834\u5408\u3082\u3001\u5fc5\u8981\u306b\u5fdc\u3058\u3066 SQL \u30d1\u30e9\u30e1\u30fc\u30bf\u304c\u81ea\u52d5\u7684\u306b\u5f15\u7528\u3001\u5909\u63db\u3001\u304a\u3088\u3073\u30a8\u30b9\u30b1\u30fc\u30d7\u3055\u308c\u308b\u3053\u3068\u306b\u6ce8\u610f\u3057\u3066\u304f\u3060\u3055\u3044\u3002<\/p>\n<p>\u30ec\u30dd\u30fc\u30c8 \u30d7\u30e9\u30b0\u30a4\u30f3 \u30af\u30e9\u30b9\u306b\u623b\u308a\u3001\u6b21\u306e\u3088\u3046\u306b\u65b0\u3057\u3044\u30e2\u30c7\u30eb \u30e1\u30bd\u30c3\u30c9\u3092\u5229\u7528\u3067\u304d\u307e\u3059\u3002<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"php\">public function run($context, $options)\n{\n  ..\n \n  \/\/ Get all active statuses from the database.\n  $statuses = $this-&gt;_model-&gt;get_statuses();\n  $status_ids = obj::get_ids($statuses);\n \n  \/\/ Read the case types and priorities from the database.\n  $types_include = $options['types_include'];\n  $types = array();\n  $types_results = array();\n \n  if ($types_include &amp;&amp; $run_ids)\n  {\n    $types = $this-&gt;_model-&gt;get_types();\n    foreach ($types as $type)\n    {\n      $types_results[$type-&gt;id] = \n        $this-&gt;_model-&gt;get_type_results(\n          $run_ids,\n          $type-&gt;id\n        );\n    }\n  }\n \n  \/* Skipped for priorities *\n \n  ..\n \n}<\/pre>\n<h2>\u30c7\u30fc\u30bf\u306e\u30ec\u30f3\u30c0\u30ea\u30f3\u30b0<\/h2>\n<p>\u5b9f\u969b\u306e\u30c7\u30fc\u30bf\u306f\u30d3\u30e5\u30fc\u306b\u3088\u3063\u3066\u9759\u7684\u306a HTML \u30da\u30fc\u30b8\u306b\u30ec\u30f3\u30c0\u30ea\u30f3\u30b0\u3055\u308c\u308b\u3053\u3068\u3092\u601d\u3044\u51fa\u3057\u3066\u304f\u3060\u3055\u3044 \u3002\u307e\u3060\u5b8c\u6210\u3057\u3066\u3044\u306a\u3044\u306e\u306f\u3001\u30c7\u30fc\u30bf\u3092\u30d3\u30e5\u30fc\u306b\u6e21\u3057\u3066\u9069\u5207\u306b\u30ec\u30f3\u30c0\u30ea\u30f3\u30b0\u3059\u308b\u90e8\u5206\u3067\u3059\u3002<a href=\"\/custom-report-1\/\" target=\"_self\" rel=\"noopener\"><strong>\u30ab\u30b9\u30bf\u30e0 \u30ec\u30dd\u30fc\u30c8 \u30d7\u30e9\u30b0\u30a4\u30f3\u306e\u4f5c\u6210\u306e\u30d1\u30fc\u30c8 1<\/strong><\/a> \u3067\u3059\u3067\u306b\u6a19\u6e96\u306e\u300c\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u300d\u30d3\u30e5\u30fc\u3092\u8a2d\u5b9a\u3057\u3066\u3042\u308b\u306e\u3067\u3001<strong>render_page<\/strong> \u306e\u547c\u3073\u51fa\u3057\u3092\u6b21\u306e\u3088\u3046\u306b\u5909\u66f4\u3057\u3066\u30c7\u30fc\u30bf\u3092\u6e21\u3059\u3053\u3068\u304c\u3067\u304d\u307e\u3059\u3002<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"php\">..\n \nreturn array(\n  'resources' =&gt; self::$_resources,\n  'html_file' =&gt; $this-&gt;render_page(\n    'index',\n    array(\n      'report' =&gt; $context['report'],\n      'project' =&gt; $project,\n      'runs' =&gt; $runs,\n      'run_rels' =&gt; $run_rels,\n      'statuses' =&gt; $statuses,\n      'types_include' =&gt; $types_include,\n      'types' =&gt; $types,\n      'types_results' =&gt; $types_results,\n      'priorities_include' =&gt; $priorities_include,\n      'priorities' =&gt; $priorities,\n      'priorities_results' =&gt; $priorities_results\n    )\n  )\n);\n \n..<\/pre>\n<p>\u30d3\u30e5\u30fc\u306e\u30bd\u30fc\u30b9 \u30b3\u30fc\u30c9\u5168\u4f53\u306f\u3001\u3053\u3053\u306b\u306f\u63b2\u8f09\u3055\u308c\u3066\u3044\u307e\u305b\u3093\u3002\u3053\u308c\u306b\u3064\u3044\u3066\u306f <a href=\"https:\/\/github.com\/gurock\/testrail-custom\/tree\/master\/reports\/tests_property_results\" target=\"_blank\" rel=\"noopener noreferrer\"><strong>TestRail \u30ab\u30b9\u30bf\u30de\u30a4\u30ba GitHub \u30ea\u30dd\u30b8\u30c8\u30ea<\/strong><\/a> \u3092\u53c2\u7167\u3057\u3066\u304f\u3060\u3055\u3044\u3002\u51e6\u7406\u3092\u8ffd\u3046\u306e\u306f\u7c21\u5358\u3067\u3059\u3002\u5358\u306b\u30ec\u30dd\u30fc\u30c8 \u30aa\u30d7\u30b7\u30e7\u30f3\u3068\u6e21\u3055\u308c\u305f\u30c7\u30fc\u30bf\u306b\u57fa\u3065\u3044\u3066 HTML \u3092\u751f\u6210\u3057\u3066\u3044\u308b\u3060\u3051\u3067\u3059\u3002<\/p>\n<p>\u307e\u3068\u3081\u308b\u3068\u3001\u30ec\u30dd\u30fc\u30c8 \u30d5\u30a9\u30fc\u30e0\u306f\u6b21\u306e\u3088\u3046\u306b\u306a\u308a\u307e\u3059\u3002<\/p>\n<p><a href=\"https:\/\/docs.testrail.techmatrix.jp\/testrail\/docs\/9\/wp-content\/uploads\/report-final.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/docs.testrail.techmatrix.jp\/testrail\/docs\/9\/wp-content\/uploads\/report-final.png\" alt=\"\" width=\"550\" height=\"837\" class=\"aligncenter size-full wp-image-9120\" srcset=\"https:\/\/docs.testrail.techmatrix.jp\/testrail\/docs\/9\/wp-content\/uploads\/report-final.png 550w, https:\/\/docs.testrail.techmatrix.jp\/testrail\/docs\/9\/wp-content\/uploads\/report-final-480x730.png 480w\" sizes=\"auto, (min-width: 0px) and (max-width: 480px) 480px, (min-width: 481px) 550px, 100vw\" \/><\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u30ab\u30b9\u30bf\u30e0 \u30ec\u30dd\u30fc\u30c8 \u30d7\u30e9\u30b0\u30a4\u30f3\u306e\u4f5c\u6210\u306e\u524d\u306e\u30d1\u30fc\u30c8\u3067\u7d39\u4ecb\u3057\u305f\u30ec\u30dd\u30fc\u30c8 \u30d8\u30eb\u30d1\u30fc\u306b\u52a0\u3048\u3066\u3001\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3078\u306e\u76f4\u63a5\u30a2\u30af\u30bb\u30b9\u3082\u30b5\u30dd\u30fc\u30c8\u3055\u308c\u3066\u3044\u307e\u3059\u3002\u3053\u306e\u6700\u5f8c\u306e\u30d1\u30fc\u30c8\u3067\u306f\u3001\u72ec\u81ea\u306e\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9 \u30e2\u30c7\u30eb\u3092\u4f5c\u6210\u3059\u308b\u3068\u3053\u308d\u304b\u3089\u3001\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9 [&hellip;]<\/p>\n","protected":false},"author":5,"featured_media":0,"parent":14805,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"_et_pb_use_builder":"","_et_pb_old_content":"","_et_gb_content_width":"","footnotes":""},"class_list":["post-17871","page","type-page","status-publish","hentry"],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/docs.testrail.techmatrix.jp\/testrail\/docs\/9\/wp-json\/wp\/v2\/pages\/17871","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/docs.testrail.techmatrix.jp\/testrail\/docs\/9\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/docs.testrail.techmatrix.jp\/testrail\/docs\/9\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/docs.testrail.techmatrix.jp\/testrail\/docs\/9\/wp-json\/wp\/v2\/users\/5"}],"replies":[{"embeddable":true,"href":"https:\/\/docs.testrail.techmatrix.jp\/testrail\/docs\/9\/wp-json\/wp\/v2\/comments?post=17871"}],"version-history":[{"count":14,"href":"https:\/\/docs.testrail.techmatrix.jp\/testrail\/docs\/9\/wp-json\/wp\/v2\/pages\/17871\/revisions"}],"predecessor-version":[{"id":17894,"href":"https:\/\/docs.testrail.techmatrix.jp\/testrail\/docs\/9\/wp-json\/wp\/v2\/pages\/17871\/revisions\/17894"}],"up":[{"embeddable":true,"href":"https:\/\/docs.testrail.techmatrix.jp\/testrail\/docs\/9\/wp-json\/wp\/v2\/pages\/14805"}],"wp:attachment":[{"href":"https:\/\/docs.testrail.techmatrix.jp\/testrail\/docs\/9\/wp-json\/wp\/v2\/media?parent=17871"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}