익명 함수를 통해 추가 된 동작 / 필터 제거


10

그것은 내가 말해야 할 무서운 나쁜 습관입니다. 지난 2 시간 동안 익명 함수를 통해 추가 된 동작 및 필터를 제거하는 솔루션을 찾았습니다.

이것은 부모 테마에 사용 된 코드이므로 제거해야합니다.

/**
 * Add custom columns to admin comments grid
 *  * Rate that user set.
 */
add_filter( 'manage_edit-comments_columns', function( $default ) {
    $columns['smr_comment_rate']  = __( 'Rate', 'txtdmn' );

    return array_slice( $default, 0, 3, true ) + $columns + array_slice( $default, 2, NULL, true );
});

toscho의 답변을 얻었고 그것을 많이 사용했지만 도움이되지 않았습니다. 익명의 기능을 통해 추가 된 액션 / 필터를 제거하는 다른 대안이 있습니까?

감사


테마 작성자에게 문의하는 것이 좋습니다. 익명 대신 이름이 지정된 함수를 사용하는 것이 비교적 쉬운 수정이며 코드를 향상시킵니다.
helgatheviking

gmazzap @ vishalbasnet23가 여기에서 한 것처럼 보입니다 : gist.github.com/vishalbasnet23/5f74df4c800681199ab0246bc037d1d5 테스트 중이며 지금까지 완벽하게 작동합니다.
Renan Oliveira

답변:


10

문제는 익명 함수와 다른 함수를 구별 할 수 없기 때문에 클로저 (즉, 익명 함수)를 제거 할 수 있지만 둘 이상의 클로저가 동일한 우선 순위로 동일한 필터에 작용하는 경우 선택해야한다는 것입니다 , 그것들을 모두 제거하십시오 .

게시 한 @toscho 답변의 기능에서 파생 된 기능을 사용하여 모두 제거하는 방법을 보여 드리겠습니다.

/**
 * Remove an object filter.
 *
 * @param  string $tag                Hook name.
 * @param  string $class              Class name. Use 'Closure' for anonymous functions.
 * @param  string|void $method        Method name. Leave empty for anonymous functions.
 * @param  string|int|void $priority  Priority
 * @return void
 */
function remove_object_filter( $tag, $class, $method = NULL, $priority = NULL ) {
  $filters = $GLOBALS['wp_filter'][ $tag ];
  if ( empty ( $filters ) ) {
    return;
  }
  foreach ( $filters as $p => $filter ) {
    if ( ! is_null($priority) && ( (int) $priority !== (int) $p ) ) continue;
    $remove = FALSE;
    foreach ( $filter as $identifier => $function ) {
      $function = $function['function'];
      if (
        is_array( $function )
        && (
          is_a( $function[0], $class )
          || ( is_array( $function ) && $function[0] === $class )
        )
      ) {
        $remove = ( $method && ( $method === $function[1] ) );
      } elseif ( $function instanceof Closure && $class === 'Closure' ) {
        $remove = TRUE;
      }
      if ( $remove ) {
        unset( $GLOBALS['wp_filter'][$tag][$p][$identifier] );
      }
    }
  }
}

remove_object_filter정적 클래스 메서드, 동적 개체 메서드 및 클로저와 같은 모든 유형의 개체 필터를 제거 할 수 있으므로 함수의 이름을 변경했습니다 .

$priority인수는 선택 사항이지만 항상 사용되어야한다 클로저를 제거 할 때, 그렇지 않으면 함수는 경우 때문에, 상관없이 어떤 우선 순위로, 필터에 추가 된 폐쇄 제거 $priority생략, 대상 클래스 / 메소드 또는 폐쇄를 사용하는 모든 필터가 있습니다를 제거되었습니다.

사용하는 방법

// remove a static method
remove_object_filter( 'a_filter_hook', 'AClass', 'a_static_method', 10 );

// remove a dynamic method
remove_object_filter( 'a_filter_hook', 'AClass', 'a_dynamic_method', 10 );

// remove a closure
remove_object_filter( 'a_filter_hook', 'Closure', NULL, 10 );

나는 이것과 다른 많은 것들을 시도했지만 그것은 작동하지 않습니다
adamj

버전 4.7 이후 @adamj, WordPress는 후크를 처리하는 새로운 방법을 도입하여 더 이상 작동하지 않습니다 ...
gmazzap

우연히 다른 대안을 알고 있습니까?
adamj

1
@adamj 나는 이것을 4.7+ 이상으로 업데이트 할 수 있었지만 지금은 시간이 없다. 이 Q / A에 연결하여이 질문이 구식이라고 말하면 누구나 답변 할 수있는 새로운 질문을 여는 것이 좋습니다. 따라서 시간이 없다면 다른 누군가가 대답 할 것입니다. 대안으로, 당신은이 Q에 현상금을 걸 수 있습니다. 여기에서 가장 많이 찬성 된 답변이 현재 버전의 WP에서는 작동하지 않는다고 설명합니다.
gmazzap

3

우선 순위가 11 인 필터를 추가하면 어떻게됩니까? 그것은 추악하지만 귀하의 경우에는 효과가있을 수 있습니다.

add_filter( 'manage_edit-comments_columns', function( $default ) {
    unset( $default['smr_comment_rate'] );

    return $default;
}, 11, 1 );

2

익명 필터 및 작업은 다음을 사용하여 기본적으로 제거 할 수 있습니다.

remove_filter( $tag, function(){}, $priority )

을 사용하여 고유 ID를 생성 할 때 spl_object_hash()익명 함수를 서로 비교할 수 있으므로 전체 클로저 오브젝트를 다시 작성할 필요가 없습니다.

여러 필터 또는 작업이 동일한 우선 순위로 동일한 태그에 연결된 경우 추가 된 최신 필터 또는 작업이 제거됩니다. 보관해야하는 필터가 있으면 제거해야하는 필터까지 모든 필터를 제거한 다음 필요에 따라 다른 필터를 다시 추가해야합니다.

// Filter which was added and needs to be removed
add_filter( 'manage_edit-comments_columns', function( $default ) {
    $columns['smr_comment_rate']  = __( 'Rate', 'txtdmn' );

    return array_slice( $default, 0, 3, true ) + $columns + array_slice( $default, 2, NULL, true );
} );

// Removes the last anonymous filter to be added
remove_filter( 'manage_edit-comments_columns', function(){} );

이것은 일반적으로 모범 사례로 돌아갑니다. 필자는 클라이언트를 위해 개발중인 사용자 지정 테마의 일부로 만 익명 함수를 사용하며 필터를 덮어 쓰거나 제거하지 않습니다. 내가 개발 한 공개 테마 나 플러그인에서 팩토리를 사용하여 클래스를 초기화하고 모든 필터와 작업을 추가 한 다음 인스턴스를 정적 ​​변수로 저장합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.