Spaces:
Sleeping
Sleeping
| defined( 'ABSPATH' ) || exit; | |
| class SA_Orch_Asterion { | |
| /** | |
| * Root directory for the Asterion ledger. | |
| * Default: WP_CONTENT_DIR/sa-asterion. Filterable. | |
| */ | |
| public static function root() { | |
| $default = WP_CONTENT_DIR . '/sa-asterion'; | |
| return apply_filters( 'sa_orch_asterion_root', $default ); | |
| } | |
| /** | |
| * Asterion-first write. The .md file is the canonical record. | |
| * Returns relative path (e.g. "arbitration/<hash>.md") or WP_Error. | |
| */ | |
| public static function write( $kind, $hash, array $frontmatter, $body ) { | |
| $root = self::root(); | |
| if ( ! is_dir( $root ) && ! wp_mkdir_p( $root ) ) { | |
| return new WP_Error( 'asterion_mkdir_failed', "Could not create root: $root" ); | |
| } | |
| $kind_safe = sanitize_file_name( $kind ); | |
| $hash_safe = sanitize_file_name( $hash ); | |
| $kind_dir = $root . '/' . $kind_safe; | |
| if ( ! is_dir( $kind_dir ) && ! wp_mkdir_p( $kind_dir ) ) { | |
| return new WP_Error( 'asterion_mkdir_failed', "Could not create kind dir: $kind_dir" ); | |
| } | |
| $rel = $kind_safe . '/' . $hash_safe . '.md'; | |
| $abs = $root . '/' . $rel; | |
| if ( file_exists( $abs ) ) { | |
| return new WP_Error( 'asterion_collision', "Ledger entry already exists: $rel" ); | |
| } | |
| $contents = "---\n" . self::build_frontmatter( $frontmatter ) . "---\n\n" . $body . "\n"; | |
| $written = @file_put_contents( $abs, $contents, LOCK_EX ); | |
| if ( $written === false ) { | |
| return new WP_Error( 'asterion_write_failed', "Could not write $abs" ); | |
| } | |
| return $rel; | |
| } | |
| private static function build_frontmatter( array $fm ) { | |
| $out = ''; | |
| foreach ( $fm as $k => $v ) { | |
| if ( is_array( $v ) ) { | |
| if ( empty( $v ) ) { | |
| $out .= "{$k}: []\n"; | |
| } else { | |
| $out .= "{$k}:\n"; | |
| foreach ( $v as $item ) { | |
| $out .= " - " . self::yaml_scalar( $item ) . "\n"; | |
| } | |
| } | |
| } else { | |
| $out .= "{$k}: " . self::yaml_scalar( $v ) . "\n"; | |
| } | |
| } | |
| return $out; | |
| } | |
| private static function yaml_scalar( $v ) { | |
| if ( $v === null ) return '~'; | |
| if ( is_bool( $v ) ) return $v ? 'true' : 'false'; | |
| if ( is_int( $v ) ) return (string) $v; | |
| if ( is_float( $v ) ) return (string) $v; | |
| $s = (string) $v; | |
| // Quote strings that contain YAML-special chars or whitespace edges | |
| if ( $s === '' || preg_match( '/[:#\-\?&\*\!\|>\'"%@`\{\}\[\],\n]/', $s ) || $s !== trim( $s ) ) { | |
| return '"' . str_replace( [ '\\', '"' ], [ '\\\\', '\\"' ], $s ) . '"'; | |
| } | |
| return $s; | |
| } | |
| } | |